mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 00:53:34 +02:00
x86/uaccess: Use unsafe wrappers for ASM GOTO
ASM GOTO is miscompiled by GCC when it is used inside a auto cleanup scope:
bool foo(u32 __user *p, u32 val)
{
scoped_guard(pagefault)
unsafe_put_user(val, p, efault);
return true;
efault:
return false;
}
It ends up leaking the pagefault disable counter in the fault path. clang
at least fails the build.
Rename unsafe_*_user() to arch_unsafe_*_user() which makes the generic
uaccess header wrap it with a local label that makes both compilers emit
correct code. Same for the kernel_nofault() variants.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/20251027083745.294359925@linutronix.de
This commit is contained in:
parent
3eb6660f26
commit
14219398e3
|
|
@ -528,18 +528,18 @@ static __must_check __always_inline bool user_access_begin(const void __user *pt
|
|||
#define user_access_save() smap_save()
|
||||
#define user_access_restore(x) smap_restore(x)
|
||||
|
||||
#define unsafe_put_user(x, ptr, label) \
|
||||
#define arch_unsafe_put_user(x, ptr, label) \
|
||||
__put_user_size((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
|
||||
|
||||
#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
|
||||
#define unsafe_get_user(x, ptr, err_label) \
|
||||
#define arch_unsafe_get_user(x, ptr, err_label) \
|
||||
do { \
|
||||
__inttype(*(ptr)) __gu_val; \
|
||||
__get_user_size(__gu_val, (ptr), sizeof(*(ptr)), err_label); \
|
||||
(x) = (__force __typeof__(*(ptr)))__gu_val; \
|
||||
} while (0)
|
||||
#else // !CONFIG_CC_HAS_ASM_GOTO_OUTPUT
|
||||
#define unsafe_get_user(x, ptr, err_label) \
|
||||
#define arch_unsafe_get_user(x, ptr, err_label) \
|
||||
do { \
|
||||
int __gu_err; \
|
||||
__inttype(*(ptr)) __gu_val; \
|
||||
|
|
@ -618,11 +618,11 @@ do { \
|
|||
} while (0)
|
||||
|
||||
#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
|
||||
#define __get_kernel_nofault(dst, src, type, err_label) \
|
||||
#define arch_get_kernel_nofault(dst, src, type, err_label) \
|
||||
__get_user_size(*((type *)(dst)), (__force type __user *)(src), \
|
||||
sizeof(type), err_label)
|
||||
#else // !CONFIG_CC_HAS_ASM_GOTO_OUTPUT
|
||||
#define __get_kernel_nofault(dst, src, type, err_label) \
|
||||
#define arch_get_kernel_nofault(dst, src, type, err_label) \
|
||||
do { \
|
||||
int __kr_err; \
|
||||
\
|
||||
|
|
@ -633,7 +633,7 @@ do { \
|
|||
} while (0)
|
||||
#endif // CONFIG_CC_HAS_ASM_GOTO_OUTPUT
|
||||
|
||||
#define __put_kernel_nofault(dst, src, type, err_label) \
|
||||
#define arch_put_kernel_nofault(dst, src, type, err_label) \
|
||||
__put_user_size(*((type *)(src)), (__force type __user *)(dst), \
|
||||
sizeof(type), err_label)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user