Hi,

I wasn't sure who to email but I believe this is somehow related to
the perf counters implementation. I kept getting lockups (deadlocks)
on a 64-bit uniprocessor system:

Linux ubuntu 3.19.0-43-generic #49~14.04.1-Ubuntu SMP Thu Dec 31
15:44:49 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

This issue seems to be reproducible on all 3.2+ < 4 kernels (possibly
earlier). On my test system, it can take from a few seconds to an hour
for a deadlock to occur.

There's some race condition (?) in x86_pmu_stop() that calls
x86_perf_event_update() that causes it to run with a user-space
pointer. The backtrace is attached. In frame #19, the event pointer is
valid and points to 0xffff88003b4ae000. However, in frame #18,
x86_perf_event_update() is called with the user-space pointer
0x40000002 in %rdi. Same applies to the vfs_write call. If this
address 0x40000002 is mmaped in user space, it might be possible to
perform arbitrary code execution via a crafted file struct, for
example.

The following disassembly (last 2 lines) shows that the call at
0xffffffff8102ba8b is executed before the value in %r12
(0xffff88003b4ae000) is copied into %rdi. So 86_perf_event_update()
runs with the old %rdi value (0x40000002). I'm not sure where this
value 0x40000002 is coming from though. The only explanation I could
find is it could be related to cpuid/rdmsr and the vmware hypervisor
since this was only reproducible on VMware hypervisors. I've also
tried qemu and virtualbox but wasn't able to reproduce it there.

(gdb) disassemble x86_pmu_stop

Dump of assembler code for function x86_pmu_stop:

   0xffffffff8102ba30 <+0>:     push   %rbp

   0xffffffff8102ba31 <+1>:     mov    %rsp,%rbp

   0xffffffff8102ba34 <+4>:     push   %r13

   0xffffffff8102ba36 <+6>:     mov    %esi,%r13d

   0xffffffff8102ba39 <+9>:     push   %r12

   0xffffffff8102ba3b <+11>:    mov    %rdi,%r12

   0xffffffff8102ba3e <+14>:    push   %rbx

   0xffffffff8102ba3f <+15>:    mov    $0xbb20,%rbx

   0xffffffff8102ba46 <+22>:    sub    $0x8,%rsp

   0xffffffff8102ba4a <+26>:    add    %gs:0x7efde6f6(%rip),%rbx
 # 0xa148 <this_cpu_off>

   0xffffffff8102ba52 <+34>:    movslq 0x154(%rdi),%rax

   0xffffffff8102ba59 <+41>:    btr    %rax,0x200(%rbx)

   0xffffffff8102ba61 <+49>:    sbb    %eax,%eax

   0xffffffff8102ba63 <+51>:    test   %eax,%eax

   0xffffffff8102ba65 <+53>:    jne    0xffffffff8102baa8 <x86_pmu_stop+120>

   0xffffffff8102ba67 <+55>:    and    $0x4,%r13d

   0xffffffff8102ba6b <+59>:    je     0xffffffff8102ba78 <x86_pmu_stop+72>

   0xffffffff8102ba6d <+61>:    testb  $0x2,0x198(%r12)

   0xffffffff8102ba76 <+70>:    je     0xffffffff8102ba88 <x86_pmu_stop+88>

   0xffffffff8102ba78 <+72>:    add    $0x8,%rsp

   0xffffffff8102ba7c <+76>:    pop    %rbx

   0xffffffff8102ba7d <+77>:    pop    %r12

   0xffffffff8102ba7f <+79>:    pop    %r13

   0xffffffff8102ba81 <+81>:    pop    %rbp

   0xffffffff8102ba82 <+82>:    retq

   0xffffffff8102ba83 <+83>:    nopl   0x0(%rax,%rax,1)

   0xffffffff8102ba88 <+88>:    mov    %r12,%rdi

   0xffffffff8102ba8b <+91>:    callq  0xffffffff8102b990
<x86_perf_event_update>


Please let me know if you need any other information.

-- 
--
Regards,
Vitaly
arch_spin_lock (lock=<optimized out>) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/arch/x86/include/asm/spinlock.h:114
114                             inc.head = READ_ONCE(lock->tickets.head);
(gdb) bt
#0  arch_spin_lock (lock=<optimized out>) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/arch/x86/include/asm/spinlock.h:114
#1  do_raw_spin_lock (lock=<optimized out>) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/include/linux/spinlock.h:158
#2  __raw_spin_lock_irq (lock=<optimized out>) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/include/linux/spinlock_api_smp.h:129
#3  _raw_spin_lock_irq (lock=0xffff8800324db808) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/locking/spinlock.c:167
#4  0xffffffff811688a8 in perf_remove_from_context (event=0xffff88003b4ae000, 
detach_group=true)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/events/core.c:1578
#5  0xffffffff81168a58 in put_event (event=0xffff88003b4ae000) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/events/core.c:3465
#6  0xffffffff81168ad0 in perf_release (inode=<optimized out>, file=<optimized 
out>)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/events/core.c:3480
#7  0xffffffff811ee117 in __fput (file=0xffff88003b610c00) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/fs/file_table.c:208
#8  0xffffffff811ee29e in ____fput (work=<optimized out>) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/fs/file_table.c:244
#9  0xffffffff81091eac in task_work_run () at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/task_work.c:115
#10 0xffffffff810773f0 in exit_task_work (task=<optimized out>) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/include/linux/task_work.h:21
#11 do_exit (code=-131940442180816) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/exit.c:745
#12 0xffffffff810187f8 in oops_end (flags=70, regs=0xffff88003257b788, signr=11)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/arch/x86/kernel/dumpstack.c:249
#13 0xffffffff81018deb in die (str=0xffffffff81a7dad7 "general protection 
fault", regs=0xffff88003257b788, err=0)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/arch/x86/kernel/dumpstack.c:312
#14 0xffffffff81015916 in do_general_protection (regs=0xffff88003257b788, 
error_code=0)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/arch/x86/kernel/traps.c:398
#15 <signal handler called>
#16 native_read_pmc (counter=1073741826) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/arch/x86/include/asm/msr.h:126
#17 0xffffffff8102b9d3 in paravirt_read_pmc (counter=<optimized out>) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/arch/x86/include/asm/paravirt.h:206
#18 x86_perf_event_update (event=0x40000002) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/arch/x86/kernel/cpu/perf_event.c:81
#19 0xffffffff8102ba90 in x86_pmu_stop (event=0xffff88003b4ae000, flags=4)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/arch/x86/kernel/cpu/perf_event.c:1171
#20 0xffffffff8102bb5a in x86_pmu_del (event=0xffff88003b4ae000, 
flags=<optimized out>)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/arch/x86/kernel/cpu/perf_event.c:1200
#21 0xffffffff81169416 in event_sched_out (event=0xffff88003b4ae000, 
ctx=0xffff8800324db800, cpuctx=<optimized out>, cpuctx=<optimized out>)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/events/core.c:1469
#22 0xffffffff81169598 in group_sched_out (group_event=<optimized out>, 
cpuctx=<optimized out>, ctx=0xffff8800324db800)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/events/core.c:1494
#23 0xffffffff81169984 in ctx_sched_out (ctx=0xffff8800324db800, 
cpuctx=0xffff88003d617ca0, event_type=EVENT_ALL)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/events/core.c:2253
#24 0xffffffff8116b7ab in perf_event_context_sched_out (next=<optimized out>, 
ctxn=<optimized out>, task=<optimized out>)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/events/core.c:2434
#25 __perf_event_task_sched_out (task=0xffff880038cfebf0, 
next=0xffff88003c986bf0) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/events/core.c:2460
#26 0xffffffff8109c903 in perf_event_task_sched_out (prev=0xffff880038cfebf0, 
next=0xffff88003c986bf0)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/include/linux/perf_event.h:712
#27 0xffffffff817b2d59 in prepare_task_switch (next=<optimized out>, 
prev=<optimized out>, rq=<optimized out>)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/sched/core.c:2231
#28 context_switch (next=<optimized out>, prev=<optimized out>, rq=<optimized 
out>) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/sched/core.c:2355
#29 __schedule () at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/sched/core.c:2850
#30 0xffffffff817b3727 in __cond_resched () at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/sched/core.c:4262
#31 _cond_resched () at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/sched/core.c:4269
#32 0xffffffff817b6219 in console_conditional_schedule () at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/kernel/printk/printk.c:2303
#33 0xffffffff8141a0bf in fbcon_redraw (vc=<optimized out>, line=<optimized 
out>, count=<optimized out>, offset=<optimized out>, p=<optimized out>)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/drivers/video/console/fbcon.c:1755
#34 0xffffffff8141b63b in fbcon_scroll (vc=0xffff88003f820c00, t=0, 
b=<optimized out>, dir=<optimized out>, count=1)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/drivers/video/console/fbcon.c:1898
#35 0xffffffff814a7dbc in scrup (vc=0xffff88003f820c00, t=0, b=37, nr=1) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/drivers/tty/vt/vt.c:324
#36 0xffffffff814a7e50 in lf (vc=0xffff88003f820c00) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/drivers/tty/vt/vt.c:1119
#37 0xffffffff814ad6d0 in do_con_write (tty=<optimized out>, buf=<optimized 
out>, count=<optimized out>)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/drivers/tty/vt/vt.c:2377
#38 0xffffffff814adb65 in do_con_write (count=<optimized out>, buf=<optimized 
out>, tty=<optimized out>)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/drivers/tty/vt/vt.c:2776
#39 con_write (tty=0xffff88003b5e2800, buf=<optimized out>, count=<optimized 
out>) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/drivers/tty/vt/vt.c:2772
#40 0xffffffff81495b9d in process_output_block (nr=<optimized out>, 
buf=<optimized out>, tty=<optimized out>)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/drivers/tty/n_tty.c:632
#41 n_tty_write (tty=0xffff88003b5e2800, file=<optimized out>, 
    buf=0xffff88003b5e6400 
"\\2\\0\\0\\0\\0\\10\\0\\0\\ffffffd4\\8\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\3\\0\\0\\0\\0\\0\\0\\0\\2\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0\\0"...,
 
    nr=233) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/drivers/tty/n_tty.c:2397
#42 0xffffffff81491ce8 in do_tty_write (count=<optimized out>, buf=<optimized 
out>, file=<optimized out>, tty=<optimized out>, write=<optimized out>)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/drivers/tty/tty_io.c:1161
#43 tty_write (file=0xffff880036163400, buf=0x7f695bb08000 <error: Cannot 
access memory at address 0x7f695bb08000>, count=<optimized out>, 
ppos=<optimized out>)
    at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/drivers/tty/tty_io.c:1247
#44 0xffffffff811ec5b7 in vfs_write (file=0x40000002, buf=0x7f695bb08000 
<error: Cannot access memory at address 0x7f695bb08000>, count=<optimized out>, 
    pos=0xffff88003257bf50) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/fs/read_write.c:546
#45 0xffffffff811ed1c6 in SYSC_write (count=<optimized out>, buf=<optimized 
out>, fd=<optimized out>)
    at /build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/fs/read_write.c:597
#46 SyS_write (fd=<optimized out>, buf=140090486587392, count=233) at 
/build/linux-lts-vivid-xAeXSD/linux-lts-vivid-3.19.0/fs/read_write.c:589
#47 <signal handler called>
#48 0x00007f695b60f870 in ?? ()
---Type <return> to continue, or q <return> to quit--- 
#49 0x00007f109ed36000 in ?? ()
#50 0x00007f109ed37000 in ?? ()
#51 0xffff88003257d380 in ?? ()
#52 0xffff88003257db00 in ?? ()
#53 0xffff88003257d6a1 in ?? ()
#54 0xffff88003257d3a0 in ?? ()
#55 0xffff88003257db20 in ?? ()
#56 0x0000000000000000 in ?? ()

Reply via email to