• Nicholas Piggin's avatar
    powerpc/uaccess: Evaluate macro arguments once, before user access is allowed · d02f6b7d
    Nicholas Piggin authored
    get/put_user() can be called with nontrivial arguments. fs/proc/page.c
    has a good example:
    
        if (put_user(stable_page_flags(ppage), out)) {
    
    stable_page_flags() is quite a lot of code, including spin locks in
    the page allocator.
    
    Ensure these arguments are evaluated before user access is allowed.
    
    This improves security by reducing code with access to userspace, but
    it also fixes a PREEMPT bug with KUAP on powerpc/64s:
    stable_page_flags() is currently called with AMR set to allow writes,
    it ends up calling spin_unlock(), which can call preempt_schedule. But
    the task switch code can not be called with AMR set (it relies on
    interrupts saving the register), so this blows up.
    
    It's fine if the code inside allow_user_access() is preemptible,
    because a timer or IPI will save the AMR, but it's not okay to
    explicitly cause a reschedule.
    
    Fixes: de78a9c4 ("powerpc: Add a framework for Kernel Userspace Access Protection")
    Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20200407041245.600651-1-npiggin@gmail.com
    d02f6b7d
uaccess.h 13.9 KB