BUG: KASAN: stack-out-of-bounds in unwind_next_frame

2018-07-18 Thread Prashant Bhole

Hi Peter, Josh,

Found following bug. This bug can not be seen with this fix: 
https://lkml.org/lkml/2018/5/10/280.


Here unwind_next_frame+0x463 is pointing at: "*ip = regs->ip;" in 
deref_stack_iret_regs().



[ 2505.084076] BUG: KASAN: stack-out-of-bounds in 
unwind_next_frame+0x463/0x850
[ 2505.084079] Read of size 8 at addr 8803d3d87970 by task 
vhost-2815/2848


[ 2505.084083] CPU: 3 PID: 2848 Comm: vhost-2815 Not tainted 4.18.0-rc3+ #13
[ 2505.084084] Hardware name: Hewlett-Packard HP Z440 Workstation/212B, 
BIOS M60 v02.34 05/18/2017

[ 2505.084085] Call Trace:
[ 2505.084087]  
[ 2505.084091]  dump_stack+0x71/0xac
[ 2505.084096]  print_address_description+0x65/0x22e
[ 2505.084099]  ? unwind_next_frame+0x463/0x850
[ 2505.084101]  kasan_report.cold.6+0x241/0x2fd
[ 2505.084104]  unwind_next_frame+0x463/0x850
[ 2505.084109]  ? native_iret+0x7/0x7
[ 2505.084111]  ? deref_stack_reg+0xd0/0xd0
[ 2505.084115]  __unwind_start+0x1c0/0x3c0
[ 2505.084117]  ? unwind_next_frame+0x850/0x850
[ 2505.084121]  ? perf_output_begin_forward+0x2df/0x460
[ 2505.084124]  ? native_iret+0x7/0x7
[ 2505.084128]  perf_callchain_kernel+0x19b/0x280
[ 2505.084131]  ? arch_perf_update_userpage+0x1a0/0x1a0
[ 2505.084134]  ? native_iret+0x7/0x7
[ 2505.084137]  get_perf_callchain+0x1f7/0x3d0
[ 2505.084140]  ? put_callchain_buffers+0x50/0x50
[ 2505.084143]  perf_prepare_sample+0x805/0x990
[ 2505.084146]  ? perf_output_sample+0xb90/0xb90
[ 2505.084151]  ? cyc2ns_read_begin.part.2+0x67/0x90
[ 2505.084154]  perf_event_output_forward+0x80/0x100
[ 2505.084157]  ? perf_prepare_sample+0x990/0x990
[ 2505.084159]  ? sched_clock+0x5/0x10
[ 2505.084161]  ? perf_adjust_period+0x117/0x270
[ 2505.084163]  ? __perf_event_account_interrupt+0x132/0x190
[ 2505.084166]  __perf_event_overflow+0xaa/0x190
[ 2505.084169]  __intel_pmu_pebs_event+0x349/0x3e0
[ 2505.084172]  ? setup_pebs_sample_data+0x890/0x890
[ 2505.084175]  ? stack_access_ok+0x35/0x80
[ 2505.084178]  ? native_iret+0x7/0x7
[ 2505.084181]  ? native_iret+0x7/0x7
[ 2505.084186]  intel_pmu_drain_pebs_nhm+0x3c4/0x590
[ 2505.084189]  ? __intel_pmu_pebs_event+0x3e0/0x3e0
[ 2505.084192]  ? ktime_get_mono_fast_ns+0xdb/0x120
[ 2505.084194]  ? intel_pmu_lbr_read+0x2e/0x7a0
[ 2505.084198]  ? watchdog_overflow_callback+0x83/0xb0
[ 2505.084201]  ? intel_bts_interrupt+0x7d/0x1a0
[ 2505.084203]  intel_pmu_handle_irq+0x200/0x670
[ 2505.084206]  ? intel_pmu_save_and_restart+0x80/0x80
[ 2505.084212]  ? cyc2ns_read_begin.part.2+0x67/0x90
[ 2505.084214]  ? native_sched_clock+0x75/0xf0
[ 2505.084217]  ? cyc2ns_read_begin.part.2+0x90/0x90
[ 2505.084220]  ? cyc2ns_read_begin.part.2+0x90/0x90
[ 2505.084223]  perf_event_nmi_handler+0x40/0x60
[ 2505.084225]  nmi_handle+0x73/0x150
[ 2505.084228]  default_do_nmi+0x57/0x110
[ 2505.084231]  do_nmi+0x141/0x1a0
[ 2505.084233]  end_repeat_nmi+0x16/0x50
[ 2505.084236] RIP: 0010:deref_stack_reg+0x76/0xd0
[ 2505.084237] Code: c7 40 04 00 f2 f2 f2 65 48 8b 04 25 28 00 00 00 48 
89 44 24 58 31 c0 e8 48 fe ff ff 31 d2 84 c0 74 23 48 89 ef 48 8d 74 24 
20  75 ff ff ff 48 8b 6c 24 20 4c 89 e7 e8 18 d3 32 00 ba 01 00 00

[ 2505.084263] RSP: 0018:8803d3d87970 EFLAGS: 0202
[ 2505.084266] RAX: 0001 RBX: 11007a7b0f2e RCX: 
a8075985
[ 2505.084267] RDX:  RSI: 8803d3d87990 RDI: 
8803d3d87e20
[ 2505.084268] RBP: 8803d3d87e20 R08: fbfff54f23db R09: 
fbfff54f23da
[ 2505.084270] R10: fbfff54f23da R11: aa791ed1 R12: 
8803d3d87b10
[ 2505.084271] R13: 0002 R14: 8803d3d87b18 R15: 
8803d3d87b00

[ 2505.084274]  ? stack_access_ok+0x35/0x80
[ 2505.084277]  ? deref_stack_reg+0x76/0xd0
[ 2505.084279]  ? deref_stack_reg+0x76/0xd0
[ 2505.084280]  
[ 2505.084281]  
[ 2505.084284]  ? __read_once_size_nocheck.constprop.7+0x10/0x10
[ 2505.084286]  ? deref_stack_reg+0xd0/0xd0
[ 2505.084288]  ? __orc_find+0x6f/0xc0
[ 2505.084291]  unwind_next_frame+0x514/0x850
[ 2505.084295]  ? __kfree_skb_flush+0x3c/0x50
[ 2505.084296]  ? __kfree_skb_flush+0x3c/0x50
[ 2505.084299]  ? deref_stack_reg+0xd0/0xd0
[ 2505.084305]  ? vhost_worker+0x147/0x1e0 [vhost]
[ 2505.084309]  ? is_module_text_address+0xa/0x11
[ 2505.084312]  ? kernel_text_address+0x4c/0x110
[ 2505.084316]  __save_stack_trace+0x82/0x100
[ 2505.084318]  ? __kfree_skb_flush+0x3c/0x50
[ 2505.084320]  save_stack+0x32/0xb0
[ 2505.084323]  ? __kasan_slab_free+0x125/0x170
[ 2505.084326]  ? kmem_cache_free_bulk+0x1af/0x3c0
[ 2505.084328]  ? __kfree_skb_flush+0x3c/0x50
[ 2505.084331]  ? net_rx_action+0x44b/0x630
[ 2505.084333]  ? __do_softirq+0x114/0x383
[ 2505.084335]  ? irq_exit+0x138/0x140
[ 2505.084337]  ? do_IRQ+0x9a/0xe0
[ 2505.084339]  ? common_interrupt+0xf/0xf
[ 2505.084345]  ? iotlb_access_ok+0x260/0x260 [vhost]
[ 2505.084348]  ? handle_rx+0x14a/0xe30 [vhost_net]
[ 2505.084353]  ? vhost_worker+0x147/0x1e0 [vhost]
[ 2505.084357]  ? kthread+0x1a0/0x1c0
[ 2505.084359]  ? ret_from_fork+0x35/0x40
[ 2505.084362]  ? skb_release_data+0x1fe/0x2d0
[ 2505.084381]  ?

Re: uprobes/perf: KASAN: use-after-free in uprobe_perf_close

2018-03-06 Thread Prashant Bhole



On 2/23/2018 2:40 AM, Oleg Nesterov wrote:

On 02/22, Peter Zijlstra wrote:


On Thu, Feb 22, 2018 at 06:04:27PM +0100, Peter Zijlstra wrote:

On Thu, Feb 22, 2018 at 05:37:15PM +0100, Oleg Nesterov wrote:



This all makes me think that we should change (fix) kernel/events/core.c...


That's going to be mighty dodgy though, holding a reference on the task
will avoid the task from dying which will avoid the events from being
destroyed which will avoid the task from dying which will... if you get
my drift :-)


Hmm, it might not be all that bad.. I need to re-read some of that code.


I was thinking about the change below below. I do not think this patch is 
actually
correct/complete, but it seems to me that if perf_event_exit_task_context() does
put_task_struct(current) then put_ctx()->put_task_struct() should go away, every
user of ctx->task should check TASK_TOMBSTONE anyway?

Oleg.

--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -1165,8 +1165,6 @@ static void put_ctx(struct perf_event_context *ctx)
if (atomic_dec_and_test(&ctx->refcount)) {
if (ctx->parent_ctx)
put_ctx(ctx->parent_ctx);
-   if (ctx->task && ctx->task != TASK_TOMBSTONE)
-   put_task_struct(ctx->task);
call_rcu(&ctx->rcu_head, free_ctx);
}
  }
@@ -3731,10 +3729,9 @@ alloc_perf_context(struct pmu *pmu, struct task_struct 
*task)
return NULL;
  
  	__perf_event_init_context(ctx);

-   if (task) {
+   if (task)
ctx->task = task;
-   get_task_struct(task);
-   }
+
ctx->pmu = pmu;
  
  	return ctx;

@@ -4109,6 +4106,8 @@ static void _free_event(struct perf_event *event)
  
  	if (event->ctx)

put_ctx(event->ctx);
+   if (event->hw.target)
+   put_task_struct(event->hw.target);
  
  	exclusive_event_destroy(event);

module_put(event->pmu->module);
@@ -9475,6 +9474,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
 * and we cannot use the ctx information because we need the
 * pmu before we get a ctx.
 */
+   get_task_struct(task);
event->hw.target = task;
}
  
@@ -9590,6 +9590,8 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,

perf_detach_cgroup(event);
if (event->ns)
put_pid_ns(event->ns);
+   if (task)
+   put_task_struct(task);
kfree(event);
  
  	return ERR_PTR(err);

@@ -10572,7 +10574,6 @@ static void perf_event_exit_task_context(struct 
task_struct *child, int ctxn)
RCU_INIT_POINTER(child->perf_event_ctxp[ctxn], NULL);
put_ctx(child_ctx); /* cannot be last */
WRITE_ONCE(child_ctx->task, TASK_TOMBSTONE);
-   put_task_struct(current); /* cannot be last */
  
  	clone_ctx = unclone_ctx(child_ctx);

raw_spin_unlock_irq(&child_ctx->lock);

Sorry for late reply. I tried these changes. It didn't fix the problem. 
With these changes, the use-after-free access of task_struct occurs at 
_free_event() for the last remaining event.


In your changes, I tried keeping get/put_task_struct() in 
perf_alloc_context()/put_ctx() intact and The problem did not occur. 
Changes are mentioned below.


-Prashant

diff --git a/kernel/events/core.c b/kernel/events/core.c
index c98cce4ceebd..65889d2b5ae2 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4109,6 +4109,8 @@ static void _free_event(struct perf_event *event)

if (event->ctx)
put_ctx(event->ctx);
+   if (event->hw.target)
+   put_task_struct(event->hw.target);

exclusive_event_destroy(event);
module_put(event->pmu->module);
@@ -9593,6 +9595,7 @@ perf_event_alloc(struct perf_event_attr *attr, int 
cpu,

 * and we cannot use the ctx information because we need the
 * pmu before we get a ctx.
 */
+   get_task_struct(task);
event->hw.target = task;
}

@@ -9708,6 +9711,8 @@ perf_event_alloc(struct perf_event_attr *attr, int 
cpu,

perf_detach_cgroup(event);
if (event->ns)
put_pid_ns(event->ns);
+   if (task)
+   put_task_struct(task);
kfree(event);

return ERR_PTR(err);




Re: uprobes/perf: KASAN: use-after-free in uprobe_perf_close

2018-04-09 Thread Prashant Bhole



On 4/9/2018 4:38 PM, Peter Zijlstra wrote:

On Tue, Mar 06, 2018 at 06:49:10PM +0900, Prashant Bhole wrote:

Sorry for late reply. I tried these changes. It didn't fix the problem. With


He, sorry for completely forgetting about this one :/


these changes, the use-after-free access of task_struct occurs at
_free_event() for the last remaining event.

In your changes, I tried keeping get/put_task_struct() in
perf_alloc_context()/put_ctx() intact and The problem did not occur. Changes
are mentioned below.


Yes, I think you're right in that this is the cleanest solution; it adds
reference counting to the exact pointer we're using.


diff --git a/kernel/events/core.c b/kernel/events/core.c
index c98cce4ceebd..65889d2b5ae2 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4109,6 +4109,8 @@ static void _free_event(struct perf_event *event)

if (event->ctx)
put_ctx(event->ctx);
+   if (event->hw.target)
+   put_task_struct(event->hw.target);

exclusive_event_destroy(event);
module_put(event->pmu->module);
@@ -9593,6 +9595,7 @@ perf_event_alloc(struct perf_event_attr *attr, int
cpu,
 * and we cannot use the ctx information because we need the
 * pmu before we get a ctx.
 */
+   get_task_struct(task);
event->hw.target = task;
}

@@ -9708,6 +9711,8 @@ perf_event_alloc(struct perf_event_attr *attr, int
cpu,
perf_detach_cgroup(event);
if (event->ns)
put_pid_ns(event->ns);
+   if (task)


Should this not too be 'event->hw.target', for consistency and clarity?



Yes, I am sending a patch with this change. Thanks.

-Prashant




[PATCH] perf/core: fix use-after-free in uprobe_perf_close

2018-04-09 Thread Prashant Bhole
A use-after-free bug was caught by KASAN while running usdt related
code. (BCC project. bcc/tests/python/test_usdt2.py)

==
BUG: KASAN: use-after-free in uprobe_perf_close+0x222/0x3b0
Read of size 4 at addr 880384f9b4a4 by task test_usdt2.py/870

CPU: 4 PID: 870 Comm: test_usdt2.py Tainted: GW 
4.16.0-next-20180409 #215
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
Ubuntu-1.8.2-1ubuntu1 04/01/2014
Call Trace:
 dump_stack+0xc7/0x15b
 ? show_regs_print_info+0x5/0x5
 ? printk+0x9c/0xc3
 ? kmsg_dump_rewind_nolock+0x6e/0x6e
 ? uprobe_perf_close+0x222/0x3b0
 print_address_description+0x83/0x3a0
 ? uprobe_perf_close+0x222/0x3b0
 kasan_report+0x1dd/0x460
 ? uprobe_perf_close+0x222/0x3b0
 uprobe_perf_close+0x222/0x3b0
 ? probes_open+0x180/0x180
 ? free_filters_list+0x290/0x290
 trace_uprobe_register+0x1bb/0x500
 ? perf_event_attach_bpf_prog+0x310/0x310
 ? probe_event_disable+0x4e0/0x4e0
 perf_uprobe_destroy+0x63/0xd0
 _free_event+0x2bc/0xbd0
 ? lockdep_rcu_suspicious+0x100/0x100
 ? ring_buffer_attach+0x550/0x550
 ? kvm_sched_clock_read+0x1a/0x30
 ? perf_event_release_kernel+0x3e4/0xc00
 ? __mutex_unlock_slowpath+0x12e/0x540
 ? wait_for_completion+0x430/0x430
 ? lock_downgrade+0x3c0/0x3c0
 ? lock_release+0x980/0x980
 ? do_raw_spin_trylock+0x118/0x150
 ? do_raw_spin_unlock+0x121/0x210
 ? do_raw_spin_trylock+0x150/0x150
 perf_event_release_kernel+0x5d4/0xc00
 ? put_event+0x30/0x30
 ? fsnotify+0xd2d/0xea0
 ? sched_clock_cpu+0x18/0x1a0
 ? __fsnotify_update_child_dentry_flags.part.0+0x1b0/0x1b0
 ? pvclock_clocksource_read+0x152/0x2b0
 ? pvclock_read_flags+0x80/0x80
 ? kvm_sched_clock_read+0x1a/0x30
 ? sched_clock_cpu+0x18/0x1a0
 ? pvclock_clocksource_read+0x152/0x2b0
 ? locks_remove_file+0xec/0x470
 ? pvclock_read_flags+0x80/0x80
 ? fcntl_setlk+0x880/0x880
 ? ima_file_free+0x8d/0x390
 ? lockdep_rcu_suspicious+0x100/0x100
 ? ima_file_check+0x110/0x110
 ? fsnotify+0xea0/0xea0
 ? kvm_sched_clock_read+0x1a/0x30
 ? rcu_note_context_switch+0x600/0x600
 perf_release+0x21/0x40
 __fput+0x264/0x620
 ? fput+0xf0/0xf0
 ? do_raw_spin_unlock+0x121/0x210
 ? do_raw_spin_trylock+0x150/0x150
 ? SyS_fchdir+0x100/0x100
 ? fsnotify+0xea0/0xea0
 task_work_run+0x14b/0x1e0
 ? task_work_cancel+0x1c0/0x1c0
 ? copy_fd_bitmaps+0x150/0x150
 ? vfs_read+0xe5/0x260
 exit_to_usermode_loop+0x17b/0x1b0
 ? trace_event_raw_event_sys_exit+0x1a0/0x1a0
 do_syscall_64+0x3f6/0x490
 ? syscall_return_slowpath+0x2c0/0x2c0
 ? lockdep_sys_exit+0x1f/0xaa
 ? syscall_return_slowpath+0x1a3/0x2c0
 ? lockdep_sys_exit+0x1f/0xaa
 ? prepare_exit_to_usermode+0x11c/0x1e0
 ? enter_from_user_mode+0x30/0x30
random: crng init done
 ? __put_user_4+0x1c/0x30
 entry_SYSCALL_64_after_hwframe+0x3d/0xa2
RIP: 0033:0x7f41d95f9340
RSP: 002b:7fffe71e4268 EFLAGS: 0246 ORIG_RAX: 0003
RAX:  RBX: 000d RCX: 7f41d95f9340
RDX:  RSI: 2401 RDI: 000d
RBP:  R08: 7f41ca8ff700 R09: 7f41d996dd1f
R10: 7fffe71e41e0 R11: 0246 R12: 7fffe71e4330
R13:  R14: fffc R15: 7fffe71e4290

Allocated by task 870:
 kasan_kmalloc+0xa0/0xd0
 kmem_cache_alloc_node+0x11a/0x430
 copy_process.part.19+0x11a0/0x41c0
 _do_fork+0x1be/0xa20
 do_syscall_64+0x198/0x490
 entry_SYSCALL_64_after_hwframe+0x3d/0xa2

Freed by task 0:
 __kasan_slab_free+0x12e/0x180
 kmem_cache_free+0x102/0x4d0
 free_task+0xfe/0x160
 __put_task_struct+0x189/0x290
 delayed_put_task_struct+0x119/0x250
 rcu_process_callbacks+0xa6c/0x1b60
 __do_softirq+0x238/0x7ae

The buggy address belongs to the object at 880384f9b480
 which belongs to the cache task_struct of size 12928

It occurs because task_struct is freed before perf_event which refers
to the task and task flags are checked while teardown of the event.
perf_event_alloc() assigns task_struct to hw.target of perf_event,
but there is no reference counting for it.

As a fix we get_task_struct() in perf_event_alloc() at above mentioned
assignment and put_task_struct() in _free_event().

Signed-off-by: Prashant Bhole 
---
 kernel/events/core.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 1922f2e0980a..734192a718ec 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4447,6 +4447,9 @@ static void _free_event(struct perf_event *event)
if (event->ctx)
put_ctx(event->ctx);
 
+   if (event->hw.target)
+   put_task_struct(event->hw.target);
+
exclusive_event_destroy(event);
module_put(event->pmu->module);
 
@@ -9955,6 +9958,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
 * and we cannot use the ctx information because we need the
 * pmu before we get a ctx.
 */
+   get_task_struct(task);
event

uprobes/perf: KASAN: use-after-free in uprobe_perf_close

2018-02-21 Thread Prashant Bhole

Hi,
I encountered following BUG caught by KASAN with recent kernels when 
trying out [BCC project] bcc/testing/python/test_usdt2.py

Tried with v4.12, it was reproducible.

--- KASAN log ---
BUG: KASAN: use-after-free in uprobe_perf_close+0x118/0x1a0
Read of size 4 at addr 8800bb2db4cc by task test_usdt2.py/1265

CPU: 2 PID: 1265 Comm: test_usdt2.py Not tainted 
4.16.0-rc2-next-20180220+ #38
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
1.10.2-1.fc26 04/01/2014

Call Trace:
 dump_stack+0x5c/0x80
 print_address_description+0x73/0x290
 kasan_report+0x257/0x380
 ? uprobe_perf_close+0x118/0x1a0
 uprobe_perf_close+0x118/0x1a0
 perf_uprobe_destroy+0x54/0x90
 _free_event+0x1a5/0x5c0
 perf_event_release_kernel+0x35e/0x620
 ? put_event+0x20/0x20
 perf_release+0x1c/0x20
 __fput+0x182/0x360
 task_work_run+0x9c/0xc0
 exit_to_usermode_loop+0xc2/0xd0
 do_syscall_64+0x244/0x250
 entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[...]
Allocated by task 1265:
 kasan_kmalloc+0xa0/0xd0
 kmem_cache_alloc_node+0x123/0x210
 copy_process.part.32+0xb9d/0x3050
 _do_fork+0x178/0x630
 do_syscall_64+0xe7/0x250
 entry_SYSCALL_64_after_hwframe+0x3d/0xa2

Freed by task 1265:
 __kasan_slab_free+0x135/0x180
 kmem_cache_free+0xaf/0x230
 rcu_process_callbacks+0x559/0xd90
 __do_softirq+0x125/0x3a2

The buggy address belongs to the object at 8800bb2db480
 which belongs to the cache task_struct of size 12928
-


After debugging, found that uprobe_perf_close() is called after task has 
been terminated and uprobe_perf_close() tries to access task_struct of 
the terminated process.


As fix I came up with following changes. Basically it gets a refcount on 
task_struct in uprobe_perf_open() and releases in uprobe_perf_close(). 
If this is a correct fix, I will submit a proper patch.



Signed-off-by: Prashant Bhole 
---
 kernel/trace/trace_uprobe.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 2014f4351ae0..b81e0a88136a 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -1039,6 +1039,7 @@ uprobe_filter_event(struct trace_uprobe *tu, 
struct perf_event *event)


 static int uprobe_perf_close(struct trace_uprobe *tu, struct 
perf_event *event)

 {
+int err = 0;
 bool done;

 write_lock(&tu->filter.rwlock);
@@ -1054,9 +1055,12 @@ static int uprobe_perf_close(struct trace_uprobe 
*tu, struct perf_event *event)

 write_unlock(&tu->filter.rwlock);

 if (!done)
-return uprobe_apply(tu->inode, tu->offset, &tu->consumer, false);
+err =  uprobe_apply(tu->inode, tu->offset, &tu->consumer, false);

-return 0;
+if (event->hw.target)
+put_task_struct(event->hw.target);
+
+return err;
 }

 static int uprobe_perf_open(struct trace_uprobe *tu, struct perf_event 
*event)
@@ -1077,6 +1081,7 @@ static int uprobe_perf_open(struct trace_uprobe 
*tu, struct perf_event *event)

 done = tu->filter.nr_systemwide ||
 event->parent || event->attr.enable_on_exec ||
 uprobe_filter_event(tu, event);
+get_task_struct(event->hw.target);
 list_add(&event->hw.tp_list, &tu->filter.perf_events);
 } else {
 done = tu->filter.nr_systemwide;
--
2.14.3


-Prashant



[tip:perf/urgent] perf/core: Fix use-after-free in uprobe_perf_close()

2018-04-09 Thread tip-bot for Prashant Bhole
Commit-ID:  621b6d2ea297d0fb6030452c5bcd221f12165fcf
Gitweb: https://git.kernel.org/tip/621b6d2ea297d0fb6030452c5bcd221f12165fcf
Author: Prashant Bhole 
AuthorDate: Mon, 9 Apr 2018 19:03:46 +0900
Committer:  Ingo Molnar 
CommitDate: Mon, 9 Apr 2018 18:15:58 +0200

perf/core: Fix use-after-free in uprobe_perf_close()

A use-after-free bug was caught by KASAN while running usdt related
code (BCC project. bcc/tests/python/test_usdt2.py):

==
BUG: KASAN: use-after-free in uprobe_perf_close+0x222/0x3b0
Read of size 4 at addr 880384f9b4a4 by task test_usdt2.py/870

CPU: 4 PID: 870 Comm: test_usdt2.py Tainted: GW 
4.16.0-next-20180409 #215
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
Ubuntu-1.8.2-1ubuntu1 04/01/2014
Call Trace:
 dump_stack+0xc7/0x15b
 ? show_regs_print_info+0x5/0x5
 ? printk+0x9c/0xc3
 ? kmsg_dump_rewind_nolock+0x6e/0x6e
 ? uprobe_perf_close+0x222/0x3b0
 print_address_description+0x83/0x3a0
 ? uprobe_perf_close+0x222/0x3b0
 kasan_report+0x1dd/0x460
 ? uprobe_perf_close+0x222/0x3b0
 uprobe_perf_close+0x222/0x3b0
 ? probes_open+0x180/0x180
 ? free_filters_list+0x290/0x290
 trace_uprobe_register+0x1bb/0x500
 ? perf_event_attach_bpf_prog+0x310/0x310
 ? probe_event_disable+0x4e0/0x4e0
 perf_uprobe_destroy+0x63/0xd0
 _free_event+0x2bc/0xbd0
 ? lockdep_rcu_suspicious+0x100/0x100
 ? ring_buffer_attach+0x550/0x550
 ? kvm_sched_clock_read+0x1a/0x30
 ? perf_event_release_kernel+0x3e4/0xc00
 ? __mutex_unlock_slowpath+0x12e/0x540
 ? wait_for_completion+0x430/0x430
 ? lock_downgrade+0x3c0/0x3c0
 ? lock_release+0x980/0x980
 ? do_raw_spin_trylock+0x118/0x150
 ? do_raw_spin_unlock+0x121/0x210
 ? do_raw_spin_trylock+0x150/0x150
 perf_event_release_kernel+0x5d4/0xc00
 ? put_event+0x30/0x30
 ? fsnotify+0xd2d/0xea0
 ? sched_clock_cpu+0x18/0x1a0
 ? __fsnotify_update_child_dentry_flags.part.0+0x1b0/0x1b0
 ? pvclock_clocksource_read+0x152/0x2b0
 ? pvclock_read_flags+0x80/0x80
 ? kvm_sched_clock_read+0x1a/0x30
 ? sched_clock_cpu+0x18/0x1a0
 ? pvclock_clocksource_read+0x152/0x2b0
 ? locks_remove_file+0xec/0x470
 ? pvclock_read_flags+0x80/0x80
 ? fcntl_setlk+0x880/0x880
 ? ima_file_free+0x8d/0x390
 ? lockdep_rcu_suspicious+0x100/0x100
 ? ima_file_check+0x110/0x110
 ? fsnotify+0xea0/0xea0
 ? kvm_sched_clock_read+0x1a/0x30
 ? rcu_note_context_switch+0x600/0x600
 perf_release+0x21/0x40
 __fput+0x264/0x620
 ? fput+0xf0/0xf0
 ? do_raw_spin_unlock+0x121/0x210
 ? do_raw_spin_trylock+0x150/0x150
 ? SyS_fchdir+0x100/0x100
 ? fsnotify+0xea0/0xea0
 task_work_run+0x14b/0x1e0
 ? task_work_cancel+0x1c0/0x1c0
 ? copy_fd_bitmaps+0x150/0x150
 ? vfs_read+0xe5/0x260
 exit_to_usermode_loop+0x17b/0x1b0
 ? trace_event_raw_event_sys_exit+0x1a0/0x1a0
 do_syscall_64+0x3f6/0x490
 ? syscall_return_slowpath+0x2c0/0x2c0
 ? lockdep_sys_exit+0x1f/0xaa
 ? syscall_return_slowpath+0x1a3/0x2c0
 ? lockdep_sys_exit+0x1f/0xaa
 ? prepare_exit_to_usermode+0x11c/0x1e0
 ? enter_from_user_mode+0x30/0x30
random: crng init done
 ? __put_user_4+0x1c/0x30
 entry_SYSCALL_64_after_hwframe+0x3d/0xa2
RIP: 0033:0x7f41d95f9340
RSP: 002b:7fffe71e4268 EFLAGS: 0246 ORIG_RAX: 0003
RAX:  RBX: 000d RCX: 7f41d95f9340
RDX:  RSI: 2401 RDI: 000d
RBP:  R08: 7f41ca8ff700 R09: 7f41d996dd1f
R10: 7fffe71e41e0 R11: 0246 R12: 7fffe71e4330
R13:  R14: fffc R15: 7fffe71e4290

Allocated by task 870:
 kasan_kmalloc+0xa0/0xd0
 kmem_cache_alloc_node+0x11a/0x430
 copy_process.part.19+0x11a0/0x41c0
 _do_fork+0x1be/0xa20
 do_syscall_64+0x198/0x490
 entry_SYSCALL_64_after_hwframe+0x3d/0xa2

Freed by task 0:
 __kasan_slab_free+0x12e/0x180
 kmem_cache_free+0x102/0x4d0
 free_task+0xfe/0x160
 __put_task_struct+0x189/0x290
 delayed_put_task_struct+0x119/0x250
 rcu_process_callbacks+0xa6c/0x1b60
 __do_softirq+0x238/0x7ae

The buggy address belongs to the object at 880384f9b480
 which belongs to the cache task_struct of size 12928

It occurs because task_struct is freed before perf_event which refers
to the task and task flags are checked while