* perf: use-after-free in perf_event_for_each @ 2017-01-23 13:30 Dmitry Vyukov 2017-01-23 17:04 ` Peter Zijlstra 2017-01-26 15:39 ` Peter Zijlstra 0 siblings, 2 replies; 9+ messages in thread From: Dmitry Vyukov @ 2017-01-23 13:30 UTC (permalink / raw) To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo, Alexander Shishkin, LKML Cc: syzkaller Hello, The following program triggers use-after-free in perf_event_for_each: https://gist.githubusercontent.com/dvyukov/f1c354a8356e42f4d0b3d912e1bec956/raw/31d7ecdf6dc2c7327b80ef8581a39c823bbe405d/gistfile1.txt BUG: KASAN: use-after-free in perf_event_for_each_child+0x15f/0x180 kernel/events/core.c:4495 at addr ffff8800680ec248 Read of size 8 by task a.out/19370 CPU: 3 PID: 19370 Comm: a.out Not tainted 4.10.0-rc5+ #186 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Call Trace: __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:328 perf_event_for_each_child+0x15f/0x180 kernel/events/core.c:4495 perf_event_for_each kernel/events/core.c:4514 [inline] _perf_ioctl kernel/events/core.c:4671 [inline] perf_ioctl+0x9b5/0x1480 kernel/events/core.c:4685 vfs_ioctl fs/ioctl.c:43 [inline] do_vfs_ioctl+0x1bf/0x1790 fs/ioctl.c:683 SYSC_ioctl fs/ioctl.c:698 [inline] SyS_ioctl+0x8f/0xc0 fs/ioctl.c:689 entry_SYSCALL_64_fastpath+0x1f/0xc2 RIP: 0033:0x44d289 RSP: 002b:00007fb128517cd8 EFLAGS: 00000217 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 000000000044d289 RDX: 0000000000010001 RSI: 0000000000002400 RDI: 0000000000000004 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000217 R12: 0000000000000000 R13: 0000000000000000 R14: 00007fb1285189c0 R15: 00007fb128518700 Object at ffff8800680ec040, in cache kmalloc-2048 size: 2048 Allocated: PID = 19367 [<ffffffff81a0942b>] kmem_cache_alloc_trace+0x10b/0x670 mm/slab.c:3629 [<ffffffff818328e5>] kzalloc include/linux/slab.h:490 [inline] [<ffffffff818328e5>] perf_event_alloc+0x1c5/0x1ef0 kernel/events/core.c:9134 [<ffffffff8184432d>] SYSC_perf_event_open+0xb8d/0x31b0 kernel/events/core.c:9692 [<ffffffff81850419>] SyS_perf_event_open+0x39/0x50 kernel/events/core.c:9586 [<ffffffff841c8c81>] entry_SYSCALL_64_fastpath+0x1f/0xc2 Freed: PID = 19372 [<ffffffff81a0b103>] __cache_free mm/slab.c:3505 [inline] [<ffffffff81a0b103>] kfree+0xd3/0x250 mm/slab.c:3822 [<ffffffff81819b6c>] free_event_rcu+0x5c/0x70 kernel/events/core.c:3828 [<ffffffff81608600>] __rcu_reclaim kernel/rcu/rcu.h:118 [inline] [<ffffffff81608600>] rcu_do_batch.isra.70+0x9e0/0xdf0 kernel/rcu/tree.c:2780 [<ffffffff81608e82>] invoke_rcu_callbacks kernel/rcu/tree.c:3043 [inline] [<ffffffff81608e82>] __rcu_process_callbacks kernel/rcu/tree.c:3010 [inline] [<ffffffff81608e82>] rcu_process_callbacks+0x472/0xc70 kernel/rcu/tree.c:3027 [<ffffffff841cbfbf>] __do_softirq+0x31f/0xbe7 kernel/softirq.c:284 On commit 095cbe66973771fecd8e8b1e8763181363ef703e (Jan 22). ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: perf: use-after-free in perf_event_for_each 2017-01-23 13:30 perf: use-after-free in perf_event_for_each Dmitry Vyukov @ 2017-01-23 17:04 ` Peter Zijlstra 2017-01-24 13:17 ` Peter Zijlstra 2017-01-26 15:39 ` Peter Zijlstra 1 sibling, 1 reply; 9+ messages in thread From: Peter Zijlstra @ 2017-01-23 17:04 UTC (permalink / raw) To: Dmitry Vyukov Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Alexander Shishkin, LKML, syzkaller On Mon, Jan 23, 2017 at 02:30:12PM +0100, Dmitry Vyukov wrote: > Hello, > > The following program triggers use-after-free in perf_event_for_each: > https://gist.githubusercontent.com/dvyukov/f1c354a8356e42f4d0b3d912e1bec956/raw/31d7ecdf6dc2c7327b80ef8581a39c823bbe405d/gistfile1.txt > > BUG: KASAN: use-after-free in perf_event_for_each_child+0x15f/0x180 > kernel/events/core.c:4495 at addr ffff8800680ec248 > Read of size 8 by task a.out/19370 > CPU: 3 PID: 19370 Comm: a.out Not tainted 4.10.0-rc5+ #186 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 > Call Trace: > __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:328 > perf_event_for_each_child+0x15f/0x180 kernel/events/core.c:4495 That's the WARN_ON_ONCE() in there, and since the object that's being UAF'ed is an event, this would be the first dereference in there, this means that this is the event passed in from the next function. > perf_event_for_each kernel/events/core.c:4514 [inline] And this is the first caller (ie, !sibling), suggesting that the line above: event = event->group_leader; is the curlprit, because the earlier event->ctx, dereference is fine (and we're holding ctx->mutex). > _perf_ioctl kernel/events/core.c:4671 [inline] > perf_ioctl+0x9b5/0x1480 kernel/events/core.c:4685 > vfs_ioctl fs/ioctl.c:43 [inline] This also matches with that the program does; which is something along the lines of: event = sys_perf_event_open(); sibling = sys_perf_event_open(.group_fd = event); dup3(sibling, event, ..); ioctl(sibling); Where the dup3() will close event (which should then promote the sibling to its own full event) and ioctl() on the sibling, which them comes apart. So it looks like something fishy on the close the leader and promote the sibling code, but I cannot put my finger on it just yet. I've ran out of time for today, but will continue staring at this tomorrow -- of course hoping that this email will give someone else ideas while I'm off :-) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: perf: use-after-free in perf_event_for_each 2017-01-23 17:04 ` Peter Zijlstra @ 2017-01-24 13:17 ` Peter Zijlstra 2017-01-24 13:29 ` Dmitry Vyukov 0 siblings, 1 reply; 9+ messages in thread From: Peter Zijlstra @ 2017-01-24 13:17 UTC (permalink / raw) To: Dmitry Vyukov Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Alexander Shishkin, LKML, syzkaller On Mon, Jan 23, 2017 at 06:04:42PM +0100, Peter Zijlstra wrote: > On Mon, Jan 23, 2017 at 02:30:12PM +0100, Dmitry Vyukov wrote: > > Hello, > > > > The following program triggers use-after-free in perf_event_for_each: > > https://gist.githubusercontent.com/dvyukov/f1c354a8356e42f4d0b3d912e1bec956/raw/31d7ecdf6dc2c7327b80ef8581a39c823bbe405d/gistfile1.txt I've been running 60 concurrent instances of that thing for hours now, and have not been able to reproduce :-/ I did enable CONFIG_KASAN but otherwise booted as normal, and the thing says: [ 0.000000] kasan: KernelAddressSanitizer initialized Is there anything else I should do? I've ran out of ideas and it would be very helpful if I could prod at something that fails... ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: perf: use-after-free in perf_event_for_each 2017-01-24 13:17 ` Peter Zijlstra @ 2017-01-24 13:29 ` Dmitry Vyukov 2017-01-24 13:49 ` Peter Zijlstra 0 siblings, 1 reply; 9+ messages in thread From: Dmitry Vyukov @ 2017-01-24 13:29 UTC (permalink / raw) To: Peter Zijlstra Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Alexander Shishkin, LKML, syzkaller On Tue, Jan 24, 2017 at 2:17 PM, Peter Zijlstra <peterz@infradead.org> wrote: > On Mon, Jan 23, 2017 at 06:04:42PM +0100, Peter Zijlstra wrote: >> On Mon, Jan 23, 2017 at 02:30:12PM +0100, Dmitry Vyukov wrote: >> > Hello, >> > >> > The following program triggers use-after-free in perf_event_for_each: >> > https://gist.githubusercontent.com/dvyukov/f1c354a8356e42f4d0b3d912e1bec956/raw/31d7ecdf6dc2c7327b80ef8581a39c823bbe405d/gistfile1.txt > > I've been running 60 concurrent instances of that thing for hours now, > and have not been able to reproduce :-/ > > I did enable CONFIG_KASAN but otherwise booted as normal, and the thing > says: > > [ 0.000000] kasan: KernelAddressSanitizer initialized > > Is there anything else I should do? Should be enough. > I've ran out of ideas and it would be very helpful if I could prod at > something that fails... Try to run more parallel processes at the same time. This program will run 32 processes in a tight loop: https://gist.githubusercontent.com/dvyukov/b36aa4398bb016923278fccdd1cc5b45/raw/9607078fd5ac2daf769c13d82561a83e17b06032/gistfile1.txt It triggered the UAF in several minutes for me. I have 4 CPUs in the VM. If you have more, set number of processes to 8*CPU. Just in case this is my config: $ grep "PERF" .config # CONFIG_CGROUP_PERF is not set CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_EVENTS=y # CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_HAVE_PERF_EVENTS_NMI=y CONFIG_HAVE_PERF_REGS=y CONFIG_HAVE_PERF_USER_STACK_DUMP=y CONFIG_PERF_EVENTS_INTEL_UNCORE=y CONFIG_PERF_EVENTS_INTEL_RAPL=y CONFIG_PERF_EVENTS_INTEL_CSTATE=y # CONFIG_PERF_EVENTS_AMD_POWER is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_PCIEASPM_PERFORMANCE is not set # CONFIG_RCU_PERF_TEST is not set And here is how I start qemu: qemu-system-x86_64 -hda wheezy.img -net user,host=10.0.2.10,hostfwd=tcp::10022-:22 -net nic -nographic -kernel arch/x86/boot/bzImage -append "kvm-intel.nested=1 kvm-intel.enable_unrestricted_guest=1 kvm-intel.ept=1 kvm-intel.flexpriority=1 kvm-intel.vpid=1 kvm-intel.emulate_invalid_guest_state=1 kvm-intel.eptad=1 kvm-intel.enable_shadow_vmcs=1 kvm-intel.pml=1 kvm-intel.enable_apicv=1 console=ttyS0 root=/dev/sda earlyprintk=serial slub_debug=UZ vsyscall=native rodata=n oops=panic panic_on_warn=1 panic=86400" -enable-kvm -pidfile vm_pid -m 2G -smp 4 -cpu host -usb -usbdevice mouse -usbdevice tablet -soundhw all ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: perf: use-after-free in perf_event_for_each 2017-01-24 13:29 ` Dmitry Vyukov @ 2017-01-24 13:49 ` Peter Zijlstra 0 siblings, 0 replies; 9+ messages in thread From: Peter Zijlstra @ 2017-01-24 13:49 UTC (permalink / raw) To: Dmitry Vyukov Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Alexander Shishkin, LKML, syzkaller On Tue, Jan 24, 2017 at 02:29:19PM +0100, Dmitry Vyukov wrote: > > Try to run more parallel processes at the same time. > This program will run 32 processes in a tight loop: > https://gist.githubusercontent.com/dvyukov/b36aa4398bb016923278fccdd1cc5b45/raw/9607078fd5ac2daf769c13d82561a83e17b06032/gistfile1.txt > It triggered the UAF in several minutes for me. I have 4 CPUs in the > VM. If you have more, set number of processes to 8*CPU. No VM here, I'll up to 320 processes. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: perf: use-after-free in perf_event_for_each 2017-01-23 13:30 perf: use-after-free in perf_event_for_each Dmitry Vyukov 2017-01-23 17:04 ` Peter Zijlstra @ 2017-01-26 15:39 ` Peter Zijlstra 2017-01-27 9:08 ` Dmitry Vyukov ` (2 more replies) 1 sibling, 3 replies; 9+ messages in thread From: Peter Zijlstra @ 2017-01-26 15:39 UTC (permalink / raw) To: Dmitry Vyukov Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Alexander Shishkin, LKML, syzkaller, Mathieu Desnoyers On Mon, Jan 23, 2017 at 02:30:12PM +0100, Dmitry Vyukov wrote: > Hello, > > The following program triggers use-after-free in perf_event_for_each: > https://gist.githubusercontent.com/dvyukov/f1c354a8356e42f4d0b3d912e1bec956/raw/31d7ecdf6dc2c7327b80ef8581a39c823bbe405d/gistfile1.txt > > BUG: KASAN: use-after-free in perf_event_for_each_child+0x15f/0x180 > kernel/events/core.c:4495 at addr ffff8800680ec248 The below seems to fix things for me. --- Subject: perf: Fix use-after-free Dmitry reported a KASAN use-after-free. XXX: do a changelog Reported-by: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> --- kernel/events/core.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 896aa53..8c1ad98 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1474,7 +1474,6 @@ ctx_group_list(struct perf_event *event, struct perf_event_context *ctx) static void list_add_event(struct perf_event *event, struct perf_event_context *ctx) { - lockdep_assert_held(&ctx->lock); WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT); @@ -1629,6 +1628,8 @@ static void perf_group_attach(struct perf_event *event) { struct perf_event *group_leader = event->group_leader, *pos; + lockdep_assert_held(&event->ctx->lock); + /* * We can have double attach due to group movement in perf_event_open. */ @@ -1702,6 +1703,8 @@ static void perf_group_detach(struct perf_event *event) struct perf_event *sibling, *tmp; struct list_head *list = NULL; + lockdep_assert_held(&event->ctx->lock); + /* * We can have double detach due to exit/hot-unplug + close. */ @@ -1900,9 +1903,29 @@ __perf_remove_from_context(struct perf_event *event, */ static void perf_remove_from_context(struct perf_event *event, unsigned long flags) { - lockdep_assert_held(&event->ctx->mutex); + struct perf_event_context *ctx = event->ctx; + + lockdep_assert_held(&ctx->mutex); event_function_call(event, __perf_remove_from_context, (void *)flags); + + /* + * The above event_function_call() can NO-OP when it hits + * TASK_TOMBSTONE. In that case we must already have been detached + * from the context (by perf_event_exit_event()) but the grouping + * might still be in-tact. + */ + WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT); + if ((flags & DETACH_GROUP) && + (event->attach_state & PERF_ATTACH_GROUP)) { + /* + * Since in that case we cannot possibly be scheduled, simply + * detach now. + */ + raw_spin_lock_irq(&ctx->lock); + perf_group_detach(event); + raw_spin_unlock_irq(&ctx->lock); + } } /* ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: perf: use-after-free in perf_event_for_each 2017-01-26 15:39 ` Peter Zijlstra @ 2017-01-27 9:08 ` Dmitry Vyukov 2017-01-27 13:02 ` Alexander Shishkin 2017-01-30 11:52 ` [tip:perf/core] perf/core: Fix use-after-free bug tip-bot for Peter Zijlstra 2 siblings, 0 replies; 9+ messages in thread From: Dmitry Vyukov @ 2017-01-27 9:08 UTC (permalink / raw) To: Peter Zijlstra Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Alexander Shishkin, LKML, syzkaller, Mathieu Desnoyers On Thu, Jan 26, 2017 at 4:39 PM, Peter Zijlstra <peterz@infradead.org> wrote: > On Mon, Jan 23, 2017 at 02:30:12PM +0100, Dmitry Vyukov wrote: >> Hello, >> >> The following program triggers use-after-free in perf_event_for_each: >> https://gist.githubusercontent.com/dvyukov/f1c354a8356e42f4d0b3d912e1bec956/raw/31d7ecdf6dc2c7327b80ef8581a39c823bbe405d/gistfile1.txt >> >> BUG: KASAN: use-after-free in perf_event_for_each_child+0x15f/0x180 >> kernel/events/core.c:4495 at addr ffff8800680ec248 > > The below seems to fix things for me. I've run the program again, it crashed machine in <1 min. Then applied your patch and run the program again, no crashes in 20 minutes. So: Tested-by: Dmitry Vyukov <dvyukov@google.com> > --- > Subject: perf: Fix use-after-free > > Dmitry reported a KASAN use-after-free. > > XXX: do a changelog > > Reported-by: Dmitry Vyukov <dvyukov@google.com> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> > --- > kernel/events/core.c | 27 +++++++++++++++++++++++++-- > 1 file changed, 25 insertions(+), 2 deletions(-) > > diff --git a/kernel/events/core.c b/kernel/events/core.c > index 896aa53..8c1ad98 100644 > --- a/kernel/events/core.c > +++ b/kernel/events/core.c > @@ -1474,7 +1474,6 @@ ctx_group_list(struct perf_event *event, struct perf_event_context *ctx) > static void > list_add_event(struct perf_event *event, struct perf_event_context *ctx) > { > - > lockdep_assert_held(&ctx->lock); > > WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT); > @@ -1629,6 +1628,8 @@ static void perf_group_attach(struct perf_event *event) > { > struct perf_event *group_leader = event->group_leader, *pos; > > + lockdep_assert_held(&event->ctx->lock); > + > /* > * We can have double attach due to group movement in perf_event_open. > */ > @@ -1702,6 +1703,8 @@ static void perf_group_detach(struct perf_event *event) > struct perf_event *sibling, *tmp; > struct list_head *list = NULL; > > + lockdep_assert_held(&event->ctx->lock); > + > /* > * We can have double detach due to exit/hot-unplug + close. > */ > @@ -1900,9 +1903,29 @@ __perf_remove_from_context(struct perf_event *event, > */ > static void perf_remove_from_context(struct perf_event *event, unsigned long flags) > { > - lockdep_assert_held(&event->ctx->mutex); > + struct perf_event_context *ctx = event->ctx; > + > + lockdep_assert_held(&ctx->mutex); > > event_function_call(event, __perf_remove_from_context, (void *)flags); > + > + /* > + * The above event_function_call() can NO-OP when it hits > + * TASK_TOMBSTONE. In that case we must already have been detached > + * from the context (by perf_event_exit_event()) but the grouping > + * might still be in-tact. > + */ > + WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT); > + if ((flags & DETACH_GROUP) && > + (event->attach_state & PERF_ATTACH_GROUP)) { > + /* > + * Since in that case we cannot possibly be scheduled, simply > + * detach now. > + */ > + raw_spin_lock_irq(&ctx->lock); > + perf_group_detach(event); > + raw_spin_unlock_irq(&ctx->lock); > + } > } > > /* ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: perf: use-after-free in perf_event_for_each 2017-01-26 15:39 ` Peter Zijlstra 2017-01-27 9:08 ` Dmitry Vyukov @ 2017-01-27 13:02 ` Alexander Shishkin 2017-01-30 11:52 ` [tip:perf/core] perf/core: Fix use-after-free bug tip-bot for Peter Zijlstra 2 siblings, 0 replies; 9+ messages in thread From: Alexander Shishkin @ 2017-01-27 13:02 UTC (permalink / raw) To: Peter Zijlstra, Dmitry Vyukov Cc: Ingo Molnar, Arnaldo Carvalho de Melo, LKML, syzkaller, Mathieu Desnoyers Peter Zijlstra <peterz@infradead.org> writes: > On Mon, Jan 23, 2017 at 02:30:12PM +0100, Dmitry Vyukov wrote: >> Hello, >> >> The following program triggers use-after-free in perf_event_for_each: >> https://gist.githubusercontent.com/dvyukov/f1c354a8356e42f4d0b3d912e1bec956/raw/31d7ecdf6dc2c7327b80ef8581a39c823bbe405d/gistfile1.txt >> >> BUG: KASAN: use-after-free in perf_event_for_each_child+0x15f/0x180 >> kernel/events/core.c:4495 at addr ffff8800680ec248 > > The below seems to fix things for me. FWIW, Reviewed-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> ^ permalink raw reply [flat|nested] 9+ messages in thread
* [tip:perf/core] perf/core: Fix use-after-free bug 2017-01-26 15:39 ` Peter Zijlstra 2017-01-27 9:08 ` Dmitry Vyukov 2017-01-27 13:02 ` Alexander Shishkin @ 2017-01-30 11:52 ` tip-bot for Peter Zijlstra 2 siblings, 0 replies; 9+ messages in thread From: tip-bot for Peter Zijlstra @ 2017-01-30 11:52 UTC (permalink / raw) To: linux-tip-commits Cc: tglx, alexander.shishkin, hpa, peterz, jolsa, acme, linux-kernel, torvalds, mathieu.desnoyers, dvyukov, syzkaller, acme, mingo Commit-ID: a76a82a3e38c8d3fb6499e3dfaeb0949241ab588 Gitweb: http://git.kernel.org/tip/a76a82a3e38c8d3fb6499e3dfaeb0949241ab588 Author: Peter Zijlstra <peterz@infradead.org> AuthorDate: Thu, 26 Jan 2017 16:39:55 +0100 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Mon, 30 Jan 2017 11:41:25 +0100 perf/core: Fix use-after-free bug Dmitry reported a KASAN use-after-free on event->group_leader. It turns out there's a hole in perf_remove_from_context() due to event_function_call() not calling its function when the task associated with the event is already dead. In this case the event will have been detached from the task, but the grouping will have been retained, such that group operations might still work properly while there are live child events etc. This does however mean that we can miss a perf_group_detach() call when the group decomposes, this in turn can then lead to use-after-free. Fix it by explicitly doing the group detach if its still required. Reported-by: Dmitry Vyukov <dvyukov@google.com> Tested-by: Dmitry Vyukov <dvyukov@google.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org # v4.5+ Cc: syzkaller <syzkaller@googlegroups.com> Fixes: 63b6da39bb38 ("perf: Fix perf_event_exit_task() race") Link: http://lkml.kernel.org/r/20170126153955.GD6515@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar <mingo@kernel.org> --- kernel/events/core.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 110b38a..4e1f4c0 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1469,7 +1469,6 @@ ctx_group_list(struct perf_event *event, struct perf_event_context *ctx) static void list_add_event(struct perf_event *event, struct perf_event_context *ctx) { - lockdep_assert_held(&ctx->lock); WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT); @@ -1624,6 +1623,8 @@ static void perf_group_attach(struct perf_event *event) { struct perf_event *group_leader = event->group_leader, *pos; + lockdep_assert_held(&event->ctx->lock); + /* * We can have double attach due to group movement in perf_event_open. */ @@ -1697,6 +1698,8 @@ static void perf_group_detach(struct perf_event *event) struct perf_event *sibling, *tmp; struct list_head *list = NULL; + lockdep_assert_held(&event->ctx->lock); + /* * We can have double detach due to exit/hot-unplug + close. */ @@ -1895,9 +1898,29 @@ __perf_remove_from_context(struct perf_event *event, */ static void perf_remove_from_context(struct perf_event *event, unsigned long flags) { - lockdep_assert_held(&event->ctx->mutex); + struct perf_event_context *ctx = event->ctx; + + lockdep_assert_held(&ctx->mutex); event_function_call(event, __perf_remove_from_context, (void *)flags); + + /* + * The above event_function_call() can NO-OP when it hits + * TASK_TOMBSTONE. In that case we must already have been detached + * from the context (by perf_event_exit_event()) but the grouping + * might still be in-tact. + */ + WARN_ON_ONCE(event->attach_state & PERF_ATTACH_CONTEXT); + if ((flags & DETACH_GROUP) && + (event->attach_state & PERF_ATTACH_GROUP)) { + /* + * Since in that case we cannot possibly be scheduled, simply + * detach now. + */ + raw_spin_lock_irq(&ctx->lock); + perf_group_detach(event); + raw_spin_unlock_irq(&ctx->lock); + } } /* ^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2017-01-30 11:54 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-01-23 13:30 perf: use-after-free in perf_event_for_each Dmitry Vyukov 2017-01-23 17:04 ` Peter Zijlstra 2017-01-24 13:17 ` Peter Zijlstra 2017-01-24 13:29 ` Dmitry Vyukov 2017-01-24 13:49 ` Peter Zijlstra 2017-01-26 15:39 ` Peter Zijlstra 2017-01-27 9:08 ` Dmitry Vyukov 2017-01-27 13:02 ` Alexander Shishkin 2017-01-30 11:52 ` [tip:perf/core] perf/core: Fix use-after-free bug tip-bot for Peter Zijlstra
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox