Message ID | 20240610210213.work.143-kees@kernel.org (mailing list archive) |
---|---|
State | Mainlined |
Commit | 8c860ed825cb85f6672cd7b10a8f33e3498a7c81 |
Headers | show |
Series | x86/uaccess: Fix missed zeroing of ia32 u64 get_user() range checking | expand |
On Tue, 11 Jun 2024 at 05:02, Kees Cook <kees@kernel.org> wrote: > > When reworking the range checking for get_user(), the get_user_8() case > on 32-bit wasn't zeroing the high register. (The jump to bad_get_user_8 > was accidentally dropped.) Restore the correct error handling > destination (and rename the jump to using the expected ".L" prefix). > > While here, switch to using a named argument ("size") for the call > template ("%c4" to "%c[size]") as already used in the other call > templates in this file. > > Found after moving the usercopy selftests to KUnit: > > # usercopy_test_invalid: EXPECTATION FAILED at > lib/usercopy_kunit.c:278 > Expected val_u64 == 0, but > val_u64 == -60129542144 (0xfffffff200000000) > > Reported-by: David Gow <davidgow@google.com> > Closes: https://lore.kernel.org/all/CABVgOSn=tb=Lj9SxHuT4_9MTjjKVxsq-ikdXC4kGHO4CfKVmGQ@mail.gmail.com > Fixes: b19b74bc99b1 ("x86/mm: Rework address range check in get_user() and put_user()") > Signed-off-by: Kees Cook <kees@kernel.org> > --- > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Ingo Molnar <mingo@redhat.com> > Cc: Borislav Petkov <bp@alien8.de> > Cc: Dave Hansen <dave.hansen@linux.intel.com> > Cc: x86@kernel.org > Cc: "H. Peter Anvin" <hpa@zytor.com> > Cc: Sean Christopherson <seanjc@google.com> > Cc: Peter Zijlstra <peterz@infradead.org> > Cc: Arnd Bergmann <arnd@arndb.de> > Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> > Cc: Qiuxu Zhuo <qiuxu.zhuo@intel.com> > Cc: Nadav Amit <nadav.amit@gmail.com> > Cc: Masahiro Yamada <masahiroy@kernel.org> > --- Thanks: this fixes it here, both under qemu and on real hardware. Tested-by: David Gow <davidgow@google.com> -- David
On Mon, Jun 10, 2024 at 02:02:27PM -0700, Kees Cook wrote: > When reworking the range checking for get_user(), the get_user_8() case > on 32-bit wasn't zeroing the high register. (The jump to bad_get_user_8 > was accidentally dropped.) Restore the correct error handling > destination (and rename the jump to using the expected ".L" prefix). > > While here, switch to using a named argument ("size") for the call > template ("%c4" to "%c[size]") as already used in the other call > templates in this file. > > Found after moving the usercopy selftests to KUnit: > > # usercopy_test_invalid: EXPECTATION FAILED at > lib/usercopy_kunit.c:278 > Expected val_u64 == 0, but > val_u64 == -60129542144 (0xfffffff200000000) > > Reported-by: David Gow <davidgow@google.com> > Closes: https://lore.kernel.org/all/CABVgOSn=tb=Lj9SxHuT4_9MTjjKVxsq-ikdXC4kGHO4CfKVmGQ@mail.gmail.com > Fixes: b19b74bc99b1 ("x86/mm: Rework address range check in get_user() and put_user()") > Signed-off-by: Kees Cook <kees@kernel.org> > --- > Cc: Thomas Gleixner <tglx@linutronix.de> > Cc: Ingo Molnar <mingo@redhat.com> > Cc: Borislav Petkov <bp@alien8.de> > Cc: Dave Hansen <dave.hansen@linux.intel.com> > Cc: x86@kernel.org > Cc: "H. Peter Anvin" <hpa@zytor.com> > Cc: Sean Christopherson <seanjc@google.com> > Cc: Peter Zijlstra <peterz@infradead.org> > Cc: Arnd Bergmann <arnd@arndb.de> > Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> > Cc: Qiuxu Zhuo <qiuxu.zhuo@intel.com> > Cc: Nadav Amit <nadav.amit@gmail.com> > Cc: Masahiro Yamada <masahiroy@kernel.org> > --- > arch/x86/include/asm/uaccess.h | 4 ++-- > arch/x86/lib/getuser.S | 6 +++++- > 2 files changed, 7 insertions(+), 3 deletions(-) > Hi, This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him a patch that has triggered this response. He used to manually respond to these common problems, but in order to save his sanity (he kept writing the same thing over and over, yet to different people), I was created. Hopefully you will not take offence and will fix the problem in your patch and resubmit it so that it can be accepted into the Linux kernel tree. You are receiving this message because of the following common error(s) as indicated below: - You have marked a patch with a "Fixes:" tag for a commit that is in an older released kernel, yet you do not have a cc: stable line in the signed-off-by area at all, which means that the patch will not be applied to any older kernel releases. To properly fix this, please follow the documented rules in the Documentation/process/stable-kernel-rules.rst file for how to resolve this. If you wish to discuss this problem further, or you have questions about how to resolve this issue, please feel free to respond to this email and Greg will reply once he has dug out from the pending patches received from other developers. thanks, greg k-h's patch email bot
> From: Kees Cook <kees@kernel.org> > [...] > Subject: [PATCH] x86/uaccess: Fix missed zeroing of ia32 u64 get_user() range > checking > > When reworking the range checking for get_user(), the get_user_8() case on > 32-bit wasn't zeroing the high register. (The jump to bad_get_user_8 was > accidentally dropped.) Restore the correct error handling destination (and > rename the jump to using the expected ".L" prefix). > > While here, switch to using a named argument ("size") for the call template > ("%c4" to "%c[size]") as already used in the other call templates in this file. > > Found after moving the usercopy selftests to KUnit: > > # usercopy_test_invalid: EXPECTATION FAILED at > lib/usercopy_kunit.c:278 > Expected val_u64 == 0, but > val_u64 == -60129542144 (0xfffffff200000000) > > Reported-by: David Gow <davidgow@google.com> > Closes: https://lore.kernel.org/all/CABVgOSn=tb=Lj9SxHuT4_9MTjjKVxsq- > ikdXC4kGHO4CfKVmGQ@mail.gmail.com > Fixes: b19b74bc99b1 ("x86/mm: Rework address range check in get_user() > and put_user()") > Signed-off-by: Kees Cook <kees@kernel.org> > [...] > arch/x86/include/asm/uaccess.h | 4 ++-- > arch/x86/lib/getuser.S | 6 +++++- > 2 files changed, 7 insertions(+), 3 deletions(-) > > diff --git a/arch/x86/include/asm/uaccess.h > b/arch/x86/include/asm/uaccess.h index 0f9bab92a43d..3a7755c1a441 > 100644 > --- a/arch/x86/include/asm/uaccess.h > +++ b/arch/x86/include/asm/uaccess.h > @@ -78,10 +78,10 @@ extern int __get_user_bad(void); > int __ret_gu; \ > register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ > __chk_user_ptr(ptr); \ > - asm volatile("call __" #fn "_%c4" \ > + asm volatile("call __" #fn "_%c[size]" \ > : "=a" (__ret_gu), "=r" (__val_gu), \ > ASM_CALL_CONSTRAINT > \ > - : "0" (ptr), "i" (sizeof(*(ptr)))); \ > + : "0" (ptr), [size] "i" (sizeof(*(ptr)))); \ > instrument_get_user(__val_gu); > \ > (x) = (__force __typeof__(*(ptr))) __val_gu; \ > __builtin_expect(__ret_gu, 0); \ > diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S index > 10d5ed8b5990..a1cb3a4e6742 100644 > --- a/arch/x86/lib/getuser.S > +++ b/arch/x86/lib/getuser.S > @@ -44,7 +44,11 @@ > or %rdx, %rax > .else > cmp $TASK_SIZE_MAX-\size+1, %eax > +.if \size != 8 > jae .Lbad_get_user > +.else > + jae .Lbad_get_user_8 > +.endif > sbb %edx, %edx /* array_index_mask_nospec() */ > and %edx, %eax > .endif > @@ -154,7 +158,7 @@ SYM_CODE_END(__get_user_handle_exception) > #ifdef CONFIG_X86_32 > SYM_CODE_START_LOCAL(__get_user_8_handle_exception) > ASM_CLAC > -bad_get_user_8: > +.Lbad_get_user_8: > xor %edx,%edx > xor %ecx,%ecx > mov $(-EFAULT),%_ASM_AX > -- > 2.34.1 LGTM. Thanks! Reviewed-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
On Mon, Jun 10, 2024 at 02:02:27PM -0700, Kees Cook wrote: > When reworking the range checking for get_user(), the get_user_8() case > on 32-bit wasn't zeroing the high register. (The jump to bad_get_user_8 > was accidentally dropped.) Restore the correct error handling > destination (and rename the jump to using the expected ".L" prefix). Oh. My bad. Reviewed-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 0f9bab92a43d..3a7755c1a441 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -78,10 +78,10 @@ extern int __get_user_bad(void); int __ret_gu; \ register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ __chk_user_ptr(ptr); \ - asm volatile("call __" #fn "_%c4" \ + asm volatile("call __" #fn "_%c[size]" \ : "=a" (__ret_gu), "=r" (__val_gu), \ ASM_CALL_CONSTRAINT \ - : "0" (ptr), "i" (sizeof(*(ptr)))); \ + : "0" (ptr), [size] "i" (sizeof(*(ptr)))); \ instrument_get_user(__val_gu); \ (x) = (__force __typeof__(*(ptr))) __val_gu; \ __builtin_expect(__ret_gu, 0); \ diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S index 10d5ed8b5990..a1cb3a4e6742 100644 --- a/arch/x86/lib/getuser.S +++ b/arch/x86/lib/getuser.S @@ -44,7 +44,11 @@ or %rdx, %rax .else cmp $TASK_SIZE_MAX-\size+1, %eax +.if \size != 8 jae .Lbad_get_user +.else + jae .Lbad_get_user_8 +.endif sbb %edx, %edx /* array_index_mask_nospec() */ and %edx, %eax .endif @@ -154,7 +158,7 @@ SYM_CODE_END(__get_user_handle_exception) #ifdef CONFIG_X86_32 SYM_CODE_START_LOCAL(__get_user_8_handle_exception) ASM_CLAC -bad_get_user_8: +.Lbad_get_user_8: xor %edx,%edx xor %ecx,%ecx mov $(-EFAULT),%_ASM_AX
When reworking the range checking for get_user(), the get_user_8() case on 32-bit wasn't zeroing the high register. (The jump to bad_get_user_8 was accidentally dropped.) Restore the correct error handling destination (and rename the jump to using the expected ".L" prefix). While here, switch to using a named argument ("size") for the call template ("%c4" to "%c[size]") as already used in the other call templates in this file. Found after moving the usercopy selftests to KUnit: # usercopy_test_invalid: EXPECTATION FAILED at lib/usercopy_kunit.c:278 Expected val_u64 == 0, but val_u64 == -60129542144 (0xfffffff200000000) Reported-by: David Gow <davidgow@google.com> Closes: https://lore.kernel.org/all/CABVgOSn=tb=Lj9SxHuT4_9MTjjKVxsq-ikdXC4kGHO4CfKVmGQ@mail.gmail.com Fixes: b19b74bc99b1 ("x86/mm: Rework address range check in get_user() and put_user()") Signed-off-by: Kees Cook <kees@kernel.org> --- Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: x86@kernel.org Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Sean Christopherson <seanjc@google.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Cc: Qiuxu Zhuo <qiuxu.zhuo@intel.com> Cc: Nadav Amit <nadav.amit@gmail.com> Cc: Masahiro Yamada <masahiroy@kernel.org> --- arch/x86/include/asm/uaccess.h | 4 ++-- arch/x86/lib/getuser.S | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-)