From: Kamil Wiatrowski Date: Mon, 5 Feb 2018 13:57:13 +0000 (+0000) Subject: intel_pmu: fix for possible null pointer dereference X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=1d80ea3884c8116f32d7f47de3a263a9da426e37;p=collectd.git intel_pmu: fix for possible null pointer dereference Null pointer dereference could occur for invalid first hardware event. In pmu_add_hw_events if the first event was not resolved, on the second iteration the eventlist_last could be dereferenced to mark previous event as group leader. Change-Id: Ic2a2a3572d6835ca892d71f3e66812f356592d9e Signed-off-by: Kamil Wiatrowski --- diff --git a/src/intel_pmu.c b/src/intel_pmu.c index fd2bd6f3..e0d796f9 100644 --- a/src/intel_pmu.c +++ b/src/intel_pmu.c @@ -204,6 +204,11 @@ static int pmu_config_hw_events(oconfig_item_t *ci) { return -EINVAL; } + if (g_ctx.hw_events) { + ERROR(PMU_PLUGIN ": Duplicate config for HardwareEvents."); + return -EINVAL; + } + g_ctx.hw_events = calloc(ci->values_num, sizeof(char *)); if (g_ctx.hw_events == NULL) { ERROR(PMU_PLUGIN ": Failed to allocate hw events."); @@ -401,12 +406,6 @@ static int pmu_add_hw_events(struct eventlist *el, char **e, size_t count) { char *s, *tmp; for (s = strtok_r(events, ",", &tmp); s; s = strtok_r(NULL, ",", &tmp)) { - /* Multiple events parsed in one entry */ - if (group_events_count == 1) { - /* Mark previously added event as group leader */ - el->eventlist_last->group_leader = 1; - } - /* Allocate memory for event struct that contains array of efd structs for all cores */ struct event *e = @@ -416,19 +415,26 @@ static int pmu_add_hw_events(struct eventlist *el, char **e, size_t count) { return -ENOMEM; } - if (resolve_event(s, &e->attr) == 0) { - e->next = NULL; - if (!el->eventlist) - el->eventlist = e; - if (el->eventlist_last) - el->eventlist_last->next = e; - el->eventlist_last = e; - e->event = strdup(s); - } else { - DEBUG(PMU_PLUGIN ": Cannot resolve %s", s); + if (resolve_event(s, &e->attr) != 0) { + WARNING(PMU_PLUGIN ": Cannot resolve %s", s); sfree(e); + continue; } + /* Multiple events parsed in one entry */ + if (group_events_count == 1) { + /* Mark previously added event as group leader */ + el->eventlist_last->group_leader = 1; + } + + e->next = NULL; + if (!el->eventlist) + el->eventlist = e; + if (el->eventlist_last) + el->eventlist_last->next = e; + el->eventlist_last = e; + e->event = strdup(s); + group_events_count++; }