• Sebastian Mayr's avatar
    uprobes/x86: Fix detection of 32-bit user mode · 941d875c
    Sebastian Mayr authored
    commit 9212ec7d upstream.
    
    32-bit processes running on a 64-bit kernel are not always detected
    correctly, causing the process to crash when uretprobes are installed.
    
    The reason for the crash is that in_ia32_syscall() is used to determine the
    process's mode, which only works correctly when called from a syscall.
    
    In the case of uretprobes, however, the function is called from a exception
    and always returns 'false' on a 64-bit kernel. In consequence this leads to
    corruption of the process's return address.
    
    Fix this by using user_64bit_mode() instead of in_ia32_syscall(), which
    is correct in any situation.
    
    [ tglx: Add a comment and the following historical info ]
    
    This should have been detected by the rename which happened in commit
    
      abfb9498 ("x86/entry: Rename is_{ia32,x32}_task() to in_{ia32,x32}_syscall()")
    
    which states in the changelog:
    
        The is_ia32_task()/is_x32_task() function names are a big misnomer: they
        suggests that the compat-ness of a system call is a task property, which
        is not true, the compatness of a system call purely depends on how it
        was invoked through the system call layer.
        .....
    
    and then it went and blindly renamed every call site.
    
    Sadly enough this was already mentioned here:
    
       8faaed1b ("uprobes/x86: Introduce sizeof_long(), cleanup adjust_ret_addr() and
    arch_uretprobe_hijack_return_addr()")
    
    where the changelog says:
    
        TODO: is_ia32_task() is not what we actually want, TS_COMPAT does
        not necessarily mean 32bit. Fortunately syscall-like insns can't be
        probed so it actually works, but it would be better to rename and
        use is_ia32_frame().
    
    and goes all the way back to:
    
        0326f5a9 ("uprobes/core: Handle breakpoint and singlestep exceptions")
    
    Oh well. 7+ years until someone actually tried a uretprobe on a 32bit
    process on a 64bit kernel....
    
    Fixes: 0326f5a9 ("uprobes/core: Handle breakpoint and singlestep exceptions")
    Signed-off-by: default avatarSebastian Mayr <me@sam.st>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Cc: Masami Hiramatsu <mhiramat@kernel.org>
    Cc: Dmitry Safonov <dsafonov@virtuozzo.com>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
    Cc: stable@vger.kernel.org
    Link: https://lkml.kernel.org/r/20190728152617.7308-1-me@sam.stSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    941d875c
uprobes.c 34.6 KB