• Oleg Nesterov's avatar
    uprobes: Change uprobe_copy_process() to dup xol_area · aa59c53f
    Oleg Nesterov authored
    This finally fixes the serious bug in uretprobes: a forked child
    crashes if the parent called fork() with the pending ret probe.
    
    Trivial test-case:
    
    	# perf probe -x /lib/libc.so.6 __fork%return
    	# perf record -e probe_libc:__fork perl -le 'fork || print "OK"'
    
    (the child doesn't print "OK", it is killed by SIGSEGV)
    
    If the child returns from the probed function it actually returns
    to trampoline_vaddr, because it got the copy of parent's stack
    mangled by prepare_uretprobe() when the parent entered this func.
    
    It crashes because a) this address is not mapped and b) until the
    previous change it doesn't have the proper->return_instances info.
    
    This means that uprobe_copy_process() has to create xol_area which
    has the trampoline slot, and its vaddr should be equal to parent's
    xol_area->vaddr.
    
    Unfortunately, uprobe_copy_process() can not simply do
    __create_xol_area(child, xol_area->vaddr). This could actually work
    but perf_event_mmap() doesn't expect the usage of foreign ->mm. So
    we offload this to task_work_run(), and pass the argument via not
    yet used utask->vaddr.
    
    We know that this vaddr is fine for install_special_mapping(), the
    necessary hole was recently "created" by dup_mmap() which skips the
    parent's VM_DONTCOPY area, and nobody else could use the new mm.
    
    Unfortunately, this also means that we can not handle the errors
    properly, we obviously can not abort the already completed fork().
    So we simply print the warning if GFP_KERNEL allocation (the only
    possible reason) fails.
    Reported-by: default avatarMartin Cermak <mcermak@redhat.com>
    Reported-by: default avatarDavid Smith <dsmith@redhat.com>
    Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
    Acked-by: default avatarSrikar Dronamraju <srikar@linux.vnet.ibm.com>
    aa59c53f
uprobes.c 46.6 KB