Patch "x86/uaccess: Fix 32-bit __get_user_asm_u64() when CC_HAS_ASM_GOTO_OUTPUT=y" has been added to the 5.14-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    x86/uaccess: Fix 32-bit __get_user_asm_u64() when CC_HAS_ASM_GOTO_OUTPUT=y

to the 5.14-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     x86-uaccess-fix-32-bit-__get_user_asm_u64-when-cc_ha.patch
and it can be found in the queue-5.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit d218acc42b96835b2d77d0cb74fd3da0dfb9451d
Author: Will Deacon <will@xxxxxxxxxx>
Date:   Mon Sep 13 17:35:47 2021 +0100

    x86/uaccess: Fix 32-bit __get_user_asm_u64() when CC_HAS_ASM_GOTO_OUTPUT=y
    
    [ Upstream commit a69ae291e1cc2d08ae77c2029579c59c9bde5061 ]
    
    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 <morbo@xxxxxxxxxx>
    Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
    Cc: Ingo Molnar <mingo@xxxxxxxxxx>
    Cc: Borislav Petkov <bp@xxxxxxxxx>
    Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
    Reported-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Fixes: 865c50e1d279 ("x86/uaccess: utilize CONFIG_CC_HAS_ASM_GOTO_OUTPUT")
    Signed-off-by: Will Deacon <will@xxxxxxxxxx>
    Reviewed-by: Nick Desaulniers <ndesaulniers@xxxxxxxxxx>
    Tested-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index c9fa7be3df82..5c95d242f38d 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -301,8 +301,8 @@ do {									\
 	unsigned int __gu_low, __gu_high;				\
 	const unsigned int __user *__gu_ptr;				\
 	__gu_ptr = (const void __user *)(ptr);				\
-	__get_user_asm(__gu_low, ptr, "l", "=r", label);		\
-	__get_user_asm(__gu_high, ptr+1, "l", "=r", label);		\
+	__get_user_asm(__gu_low, __gu_ptr, "l", "=r", label);		\
+	__get_user_asm(__gu_high, __gu_ptr+1, "l", "=r", label);	\
 	(x) = ((unsigned long long)__gu_high << 32) | __gu_low;		\
 } while (0)
 #else



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux