Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Tal Well <talwell02@gmail.com>
To: linux@armlinux.org.uk
Cc: linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, Tal Well <talwell02@gmail.com>
Subject: [PATCH] ARM: Fix potential register clobbering in __get_user_check
Date: Sat, 13 Jun 2026 15:27:07 +0300	[thread overview]
Message-ID: <20260613122707.512353-1-talwell02@gmail.com> (raw)

This can happen due to local variable registers being call-clobbered by
uaccess_save_and_enable or uaccess_restore, which can happen if they
become slightly more complicated than they are (for example contain any
memory access while KASAN is enabled).
In that case, the first user access will fail while trying to execute
the init process and the kernel will panic.

While this is not strictly a bug given r0, r1 and r2 remain unused in
the uaccess functions, even something as simple as making them noinline
breaks this assumption and there's no reason to rely on it.

This is similar to the issue fixed by commit df909df0770779f1a556
("ARM: 9132/1: Fix __get_user_check failure with ARM KASAN images"),
but that only handled clobbering of r0 by the uaccess_restore function.

Signed-off-by: Tal Well <talwell02@gmail.com>
---
 arch/arm/include/asm/uaccess.h | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index d6ae80b5df36..290ce8710773 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -180,12 +180,13 @@ extern int __get_user_64t_4(void *);
 
 #define __get_user_check(x, p)						\
 	({								\
-		unsigned long __limit = TASK_SIZE - 1; \
+		unsigned long __limit = TASK_SIZE - 1;			\
+		unsigned int __ua_flags = uaccess_save_and_enable();	\
 		register typeof(*(p)) __user *__p asm("r0") = (p);	\
 		register __inttype(x) __r2 asm("r2");			\
 		register unsigned long __l asm("r1") = __limit;		\
 		register int __e asm("r0");				\
-		unsigned int __ua_flags = uaccess_save_and_enable();	\
+		__inttype(x) __tmp_r2;					\
 		int __tmp_e;						\
 		switch (sizeof(*(__p))) {				\
 		case 1:							\
@@ -214,9 +215,10 @@ extern int __get_user_64t_4(void *);
 			break;						\
 		default: __e = __get_user_bad(); break;			\
 		}							\
+		__tmp_r2 = __r2;					\
 		__tmp_e = __e;						\
 		uaccess_restore(__ua_flags);				\
-		x = (typeof(*(p))) __r2;				\
+		x = (typeof(*(p))) __tmp_r2;				\
 		__tmp_e;						\
 	})
 

base-commit: 062871f1371b2e02a272ff5279c6479aff0a37ef
-- 
2.39.5



                 reply	other threads:[~2026-06-13 12:27 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260613122707.512353-1-talwell02@gmail.com \
    --to=talwell02@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox