perf/core: make account/unaccount_sb_event consistent
PATCH 1/1 perf/core: make account/unaccount_sb_event consistent
unaccount_pmu_sb_event did not check for attributes in event->attr before calling detach_sb_event, while account_pmu_event did.
This caused NULL pointer reference in cgroup events that did not have any of the attributes checked by account_pmu_event.
To trigger the bug just wait for a cgroup event to terminate, e.g.:
$ mkdir /dev/cgroup/devices/test $ perf stat -e cycles -a -G test sleep 0
... see crash ...
Patch rebased on peterz/queue/perf/core .
--- kernel/events/core.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-)
kernel/events/core.c +18 -16
@@ -3682,15 +3682,28 @@ static void detach_sb_event(struct perf_event *event)raw_spin_unlock (&pel->lock); } -static void unaccount_pmu_sb_event (struct perf_event *event) +static bool is_sb_event (struct perf_event *event) { +struct perf_event_attr *attr = &event->attr; +if (event->parent) -return ; +return false;if (event->attach_state &PERF_ATTACH_TASK ) -return ; +return false; -detach_sb_event (event); +if (attr->mmap || attr->mmap_data || attr->mmap2 || + attr->comm || attr->comm_exec || + attr->task || + attr->context_switch) +return true; +return false; +} + +static void unaccount_pmu_sb_event (struct perf_event *event) +{ +if (is_sb_event (event)) +detach_sb_event (event); }static void unaccount_event_cpu (struct perf_event *event,int cpu)
@@ -8666,18 +8679,7 @@ static void attach_sb_event(struct perf_event *event)*/ static void account_pmu_sb_event (struct perf_event *event) { -struct perf_event_attr *attr = &event->attr; - -if (event->parent) -return ; - -if (event->attach_state &PERF_ATTACH_TASK ) -return ; - -if (attr->mmap || attr->mmap_data || attr->mmap2 || - attr->comm || attr->comm_exec || - attr->task || - attr->context_switch) +if (is_sb_event (event))attach_sb_event (event); }
Signature · 1 line
2.8.0.rc3.226.g39d4020
Quoted 13 lines · David Carrillo-Cisneros
unaccount_pmu_sb_eventdid not check for attributes inevent->attrbefore callingdetach_sb_event, whileaccount_pmu_eventdid.This caused NULL pointer reference in cgroup events that did not have any of the attributes checked by
account_pmu_event.To trigger the bug just wait for a cgroup event to terminate, e.g.:
$ mkdir /dev/cgroup/devices/test $ perf stat -e cycles -a -G test sleep 0... see crash ...
Quoted 7 lines
Patch rebased on peterz/queue/perf/core .
Reviewed-by Stephane Eranian <[email protected]>Signed-off-by David Carrillo-Cisneros <[email protected]>--- kernel/events/core.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-)
Signature · 4 lines
Regards/Gruss,
Boris.
ECO tip #101: Trim your mails when you reply.tip-bot for David Carrillo-Cisneros
merge bot[tip:perf/core] perf/core: Fix crash due to account/unaccount_sb_event() inconsistency
In reply to David Carrillo-Cisnerosperf/core: Fix crash due to account/unaccount_sb_event() inconsistency
Commit-ID: a4f144ebbdf6f7807c477bce8e136047ed27321f Gitweb: http://git.kernel.org/tip/a4f144ebbdf6f7807c477bce8e136047ed27321f Author: David Carrillo-Cisneros <[email protected]> AuthorDate: Wed, 1 Jun 2016 12:33:05 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Wed, 8 Jun 2016 09:18:45 +0200
perf/core: Fix crash due to account/unaccount_sb_event() inconsistency
unaccount_pmu_sb_event() did not check for attributes in event->attr before calling detach_sb_event(), while account_pmu_event() did.
This caused NULL pointer reference in cgroup events that did not have any of the attributes checked by account_pmu_event().
To trigger the bug just wait for a cgroup event to terminate, e.g.:
$ mkdir /dev/cgroup/devices/test $ perf stat -e cycles -a -G test sleep 0
... see crash ...
--- kernel/events/core.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-)
kernel/events/core.c +18 -16
@@ -3682,15 +3682,28 @@ static void detach_sb_event(struct perf_event *event)raw_spin_unlock (&pel->lock); } -static void unaccount_pmu_sb_event (struct perf_event *event) +static bool is_sb_event (struct perf_event *event) { +struct perf_event_attr *attr = &event->attr; +if (event->parent) -return ; +return false;if (event->attach_state &PERF_ATTACH_TASK ) -return ; +return false; -detach_sb_event (event); +if (attr->mmap || attr->mmap_data || attr->mmap2 || + attr->comm || attr->comm_exec || + attr->task || + attr->context_switch) +return true; +return false; +} + +static void unaccount_pmu_sb_event (struct perf_event *event) +{ +if (is_sb_event (event)) +detach_sb_event (event); }static void unaccount_event_cpu (struct perf_event *event,int cpu)
@@ -8666,18 +8679,7 @@ static void attach_sb_event(struct perf_event *event)*/ static void account_pmu_sb_event (struct perf_event *event) { -struct perf_event_attr *attr = &event->attr; - -if (event->parent) -return ; - -if (event->attach_state &PERF_ATTACH_TASK ) -return ; - -if (attr->mmap || attr->mmap_data || attr->mmap2 || - attr->comm || attr->comm_exec || - attr->task || - attr->context_switch) +if (is_sb_event (event))attach_sb_event (event); }