[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <f8872b02-d7f5-421d-8699-5d27987c6e1f@csgroup.eu>
Date: Tue, 4 Nov 2025 07:15:30 +0100
From: Christophe Leroy <christophe.leroy@...roup.eu>
To: Thomas Gleixner <tglx@...utronix.de>, LKML <linux-kernel@...r.kernel.org>
Cc: Madhavan Srinivasan <maddy@...ux.ibm.com>,
Michael Ellerman <mpe@...erman.id.au>, Nicholas Piggin <npiggin@...il.com>,
linuxppc-dev@...ts.ozlabs.org, kernel test robot <lkp@...el.com>,
Russell King <linux@...linux.org.uk>, linux-arm-kernel@...ts.infradead.org,
Linus Torvalds <torvalds@...ux-foundation.org>, x86@...nel.org,
Paul Walmsley <pjw@...nel.org>, Palmer Dabbelt <palmer@...belt.com>,
linux-riscv@...ts.infradead.org, Heiko Carstens <hca@...ux.ibm.com>,
Christian Borntraeger <borntraeger@...ux.ibm.com>,
Sven Schnelle <svens@...ux.ibm.com>, linux-s390@...r.kernel.org,
Mathieu Desnoyers <mathieu.desnoyers@...icios.com>,
Andrew Cooper <andrew.cooper3@...rix.com>,
David Laight <david.laight.linux@...il.com>,
Julia Lawall <Julia.Lawall@...ia.fr>, Nicolas Palix <nicolas.palix@...g.fr>,
Peter Zijlstra <peterz@...radead.org>, Darren Hart <dvhart@...radead.org>,
Davidlohr Bueso <dave@...olabs.net>, André Almeida
<andrealmeid@...lia.com>, Alexander Viro <viro@...iv.linux.org.uk>,
Christian Brauner <brauner@...nel.org>, Jan Kara <jack@...e.cz>,
linux-fsdevel@...r.kernel.org
Subject: Re: [patch V5 04/12] powerpc/uaccess: Use unsafe wrappers for ASM
GOTO
Le 27/10/2025 à 09:43, Thomas Gleixner a écrit :
> 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.
Confirmed on powerpc:
Before the patch
000001e8 <foo>:
1e8: 81 22 05 24 lwz r9,1316(r2)
1ec: 39 29 00 01 addi r9,r9,1
1f0: 91 22 05 24 stw r9,1316(r2)
1f4: 90 83 00 00 stw r4,0(r3)
1f8: 81 22 05 24 lwz r9,1316(r2)
1fc: 38 60 00 01 li r3,1
200: 39 29 ff ff addi r9,r9,-1
204: 91 22 05 24 stw r9,1316(r2)
208: 4e 80 00 20 blr
20c: 38 60 00 00 li r3,0
210: 4e 80 00 20 blr
00000000 <__ex_table>:
...
20: R_PPC_REL32 .text+0x1f4
24: R_PPC_REL32 .text+0x20c
After the patch
000001e8 <foo>:
1e8: 81 22 05 24 lwz r9,1316(r2)
1ec: 39 29 00 01 addi r9,r9,1
1f0: 91 22 05 24 stw r9,1316(r2)
1f4: 90 83 00 00 stw r4,0(r3)
1f8: 81 22 05 24 lwz r9,1316(r2)
1fc: 38 60 00 01 li r3,1
200: 39 29 ff ff addi r9,r9,-1
204: 91 22 05 24 stw r9,1316(r2)
208: 4e 80 00 20 blr
20c: 81 22 05 24 lwz r9,1316(r2)
210: 38 60 00 00 li r3,0
214: 39 29 ff ff addi r9,r9,-1
218: 91 22 05 24 stw r9,1316(r2)
21c: 4e 80 00 20 blr
00000000 <__ex_table>:
...
20: R_PPC_REL32 .text+0x1f4
24: R_PPC_REL32 .text+0x20c
>
> 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@...utronix.de>
> Cc: Madhavan Srinivasan <maddy@...ux.ibm.com>
> Cc: Michael Ellerman <mpe@...erman.id.au>
> Cc: Nicholas Piggin <npiggin@...il.com>
> Cc: Christophe Leroy <christophe.leroy@...roup.eu>
> Cc: linuxppc-dev@...ts.ozlabs.org
Reviewed-by: Christophe Leroy <christophe.leroy@...roup.eu>
> ---
> arch/powerpc/include/asm/uaccess.h | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> --- a/arch/powerpc/include/asm/uaccess.h
> +++ b/arch/powerpc/include/asm/uaccess.h
> @@ -451,7 +451,7 @@ user_write_access_begin(const void __use
> #define user_write_access_begin user_write_access_begin
> #define user_write_access_end prevent_current_write_to_user
>
> -#define unsafe_get_user(x, p, e) do { \
> +#define arch_unsafe_get_user(x, p, e) do { \
> __long_type(*(p)) __gu_val; \
> __typeof__(*(p)) __user *__gu_addr = (p); \
> \
> @@ -459,7 +459,7 @@ user_write_access_begin(const void __use
> (x) = (__typeof__(*(p)))__gu_val; \
> } while (0)
>
> -#define unsafe_put_user(x, p, e) \
> +#define arch_unsafe_put_user(x, p, e) \
> __put_user_size_goto((__typeof__(*(p)))(x), (p), sizeof(*(p)), e)
>
> #define unsafe_copy_from_user(d, s, l, e) \
> @@ -504,11 +504,11 @@ do { \
> unsafe_put_user(*(u8*)(_src + _i), (u8 __user *)(_dst + _i), e); \
> } while (0)
>
> -#define __get_kernel_nofault(dst, src, type, err_label) \
> +#define arch_get_kernel_nofault(dst, src, type, err_label) \
> __get_user_size_goto(*((type *)(dst)), \
> (__force type __user *)(src), sizeof(type), err_label)
>
> -#define __put_kernel_nofault(dst, src, type, err_label) \
> +#define arch_put_kernel_nofault(dst, src, type, err_label) \
> __put_user_size_goto(*((type *)(src)), \
> (__force type __user *)(dst), sizeof(type), err_label)
>
>
Powered by blists - more mailing lists