Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

authored by

Thomas Gleixner and committed by
Peter Zijlstra
14219398 3eb6660f

+6 -6
+6 -6
arch/x86/include/asm/uaccess.h
··· 528 528 #define user_access_save() smap_save() 529 529 #define user_access_restore(x) smap_restore(x) 530 530 531 - #define unsafe_put_user(x, ptr, label) \ 531 + #define arch_unsafe_put_user(x, ptr, label) \ 532 532 __put_user_size((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label) 533 533 534 534 #ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT 535 - #define unsafe_get_user(x, ptr, err_label) \ 535 + #define arch_unsafe_get_user(x, ptr, err_label) \ 536 536 do { \ 537 537 __inttype(*(ptr)) __gu_val; \ 538 538 __get_user_size(__gu_val, (ptr), sizeof(*(ptr)), err_label); \ 539 539 (x) = (__force __typeof__(*(ptr)))__gu_val; \ 540 540 } while (0) 541 541 #else // !CONFIG_CC_HAS_ASM_GOTO_OUTPUT 542 - #define unsafe_get_user(x, ptr, err_label) \ 542 + #define arch_unsafe_get_user(x, ptr, err_label) \ 543 543 do { \ 544 544 int __gu_err; \ 545 545 __inttype(*(ptr)) __gu_val; \ ··· 618 618 } while (0) 619 619 620 620 #ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT 621 - #define __get_kernel_nofault(dst, src, type, err_label) \ 621 + #define arch_get_kernel_nofault(dst, src, type, err_label) \ 622 622 __get_user_size(*((type *)(dst)), (__force type __user *)(src), \ 623 623 sizeof(type), err_label) 624 624 #else // !CONFIG_CC_HAS_ASM_GOTO_OUTPUT 625 - #define __get_kernel_nofault(dst, src, type, err_label) \ 625 + #define arch_get_kernel_nofault(dst, src, type, err_label) \ 626 626 do { \ 627 627 int __kr_err; \ 628 628 \ ··· 633 633 } while (0) 634 634 #endif // CONFIG_CC_HAS_ASM_GOTO_OUTPUT 635 635 636 - #define __put_kernel_nofault(dst, src, type, err_label) \ 636 + #define arch_put_kernel_nofault(dst, src, type, err_label) \ 637 637 __put_user_size(*((type *)(src)), (__force type __user *)(dst), \ 638 638 sizeof(type), err_label) 639 639