aboutsummaryrefslogtreecommitdiff
path: root/include/linux/compiler-gcc.h
diff options
context:
space:
mode:
authorWill Deacon <[email protected]>2021-09-13 17:35:47 +0100
committerLinus Torvalds <[email protected]>2021-09-13 09:59:35 -0700
commita69ae291e1cc2d08ae77c2029579c59c9bde5061 (patch)
treeb11e29d7790ebdf41099d2e241792d6923b6814e /include/linux/compiler-gcc.h
parent6880fa6c56601bb8ed59df6c30fd390cc5f6dd8f (diff)
x86/uaccess: Fix 32-bit __get_user_asm_u64() when CC_HAS_ASM_GOTO_OUTPUT=y
Commit 865c50e1d279 ("x86/uaccess: utilize CONFIG_CC_HAS_ASM_GOTO_OUTPUT") added an optimised version of __get_user_asm() for x86 using 'asm goto'. Like the non-optimised code, the 32-bit implementation of 64-bit get_user() expands to a pair of 32-bit accesses. Unlike the non-optimised code, the _original_ pointer is incremented to copy the high word instead of loading through a new pointer explicitly constructed to point at a 32-bit type. Consequently, if the pointer points at a 64-bit type then we end up loading the wrong data for the upper 32-bits. This was observed as a mount() failure in Android targeting i686 after b0cfcdd9b967 ("d_path: make 'prepend()' fill up the buffer exactly on overflow") because the call to copy_from_kernel_nofault() from prepend_copy() ends up in __get_kernel_nofault() and casts the source pointer to a 'u64 __user *'. An attempt to mount at "/debug_ramdisk" therefore ends up failing trying to mount "/debumdismdisk". Use the existing '__gu_ptr' source pointer to unsigned int for 32-bit __get_user_asm_u64() instead of the original pointer. Cc: Bill Wendling <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Peter Zijlstra <[email protected]> Reported-by: Greg Kroah-Hartman <[email protected]> Fixes: 865c50e1d279 ("x86/uaccess: utilize CONFIG_CC_HAS_ASM_GOTO_OUTPUT") Signed-off-by: Will Deacon <[email protected]> Reviewed-by: Nick Desaulniers <[email protected]> Tested-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
Diffstat (limited to 'include/linux/compiler-gcc.h')
0 files changed, 0 insertions, 0 deletions