All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/uaccess: Zero the 8-byte get_range case on failure
@ 2024-07-31  7:30 David Gow
  2024-07-31 16:24 ` Linus Torvalds
  2024-08-01 19:28 ` [tip: x86/urgent] x86/uaccess: Zero the 8-byte get_range case on failure on 32-bit tip-bot2 for David Gow
  0 siblings, 2 replies; 7+ messages in thread
From: David Gow @ 2024-07-31  7:30 UTC (permalink / raw)
  To: Kees Cook, Linus Torvalds, Borislav Petkov
  Cc: David Gow, Thomas Gleixner, Ingo Molnar, Dave Hansen,
	Peter Zijlstra, Andrew Morton, H . Peter Anvin, x86, kunit-dev,
	linux-kernel

While zeroing the upper 32 bits of an 8-byte getuser on 32-bit x86 was
fixed by commit 8c860ed825cb ("x86/uaccess: Fix missed zeroing of ia32 u64 get_user() range checking")
it was broken again in commit 8a2462df1547 ("x86/uaccess: Improve the 8-byte getuser() case").

This is because the register which holds the upper 32 bits (%ecx) is
being cleared _after_ the check_range, so if the range check fails, %ecx
is never cleared.

This can be reproduced with:
./tools/testing/kunit/kunit.py run --arch i386 usercopy

Instead, clear %ecx _before_ check_range in the 8-byte case. This
reintroduces a bit of the ugliness we were trying to avoid by adding
another #ifndef CONFIG_X86_64, but at least keeps check_range from
needing a separate bad_get_user_8 jump.

Fixes: 8a2462df1547 ("x86/uaccess: Improve the 8-byte getuser() case")
Signed-off-by: David Gow <davidgow@google.com>
---

There are a few other ways we could fix this, but all of them seem to
increase the ugliness a bit. This seemed the best compromise, but if
you'd prefer to have the size=8 special case live in check_range, that's
fine, too.

See also:
https://lore.kernel.org/lkml/CAHk-=whYb2L_atsRk9pBiFiVLGe5wNZLHhRinA69yu6FiKvDsw@mail.gmail.com/

Cheers,
-- David

---
 arch/x86/lib/getuser.S | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/lib/getuser.S b/arch/x86/lib/getuser.S
index a314622aa093..d066aecf8aeb 100644
--- a/arch/x86/lib/getuser.S
+++ b/arch/x86/lib/getuser.S
@@ -88,12 +88,14 @@ SYM_FUNC_END(__get_user_4)
 EXPORT_SYMBOL(__get_user_4)
 
 SYM_FUNC_START(__get_user_8)
+#ifndef CONFIG_X86_64
+	xor %ecx,%ecx
+#endif
 	check_range size=8
 	ASM_STAC
 #ifdef CONFIG_X86_64
 	UACCESS movq (%_ASM_AX),%rdx
 #else
-	xor %ecx,%ecx
 	UACCESS movl (%_ASM_AX),%edx
 	UACCESS movl 4(%_ASM_AX),%ecx
 #endif
-- 
2.46.0.rc1.232.g9752f9e123-goog


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-08-01 19:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-31  7:30 [PATCH] x86/uaccess: Zero the 8-byte get_range case on failure David Gow
2024-07-31 16:24 ` Linus Torvalds
2024-07-31 16:38   ` Linus Torvalds
2024-08-01  6:34     ` David Gow
2024-08-01 16:24       ` Linus Torvalds
2024-08-01 19:08         ` Thomas Gleixner
2024-08-01 19:28 ` [tip: x86/urgent] x86/uaccess: Zero the 8-byte get_range case on failure on 32-bit tip-bot2 for David Gow

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.