[PATCH v3] x86/uaccess: Drop the address space qualifier from put_user()
From: Ricardo Ribalda
Date: Fri Nov 13 2026 - 09:41:41 EST
__typeof__() preserves every qualifier, the address space included.
When we do __typeof(*__user *int), we are declaring a __user integer,
which is pretty much meaningless. A value in a register or in the stack
does not live in the user address space.
This annotation did not trigger any error until a recent version of
smatch[1] started caring. And as a result of that now we have tens of
warnings like:
drivers/media/usb/uvc/uvc_v4l2.c:1112:13: warning: incorrect type in argument 2 (different address spaces)
drivers/media/usb/uvc/uvc_v4l2.c:1112:13: expected void const *from
drivers/media/usb/uvc/uvc_v4l2.c:1112:13: got unsigned int __user *
Use TYPEOF_NO_ADDRESS_SPACE() instead of __typeof__(). Unlike
TYPEOF_UNQUAL(), TYPEOF_NO_ADDRESS_SPACE() only strips qualifiers when
running with sparse, while expanding to __typeof__() for normal
compiler builds. This preserves const/volatile mismatch checking and
has no impact on compilers that do not support __typeof_unqual__(),
which is why TYPEOF_UNQUAL() is not used here.
[1] https://github.com/error27/smatch/commit/e53027a4e816a772403baafa83c09e4a94c1cb8f
Suggested-by: Dan Carpenter <error27@xxxxxxxxx>
Link: https://lore.kernel.org/r/20260825-unqual-v1-2-7024fb81b4f9@xxxxxxxxxxxx
Signed-off-by: Ricardo Ribalda <ribalda@xxxxxxxxxxxx>
---
Recent versions of smatch preserve the address space qualifiers while
running typeof() [1]. This has triggered tens of new sparse warnings in
media-ci.
The RCU patch from earlier revisions has already been merged as commit
0381ade2ea82 ("rcu: Drop the address space qualifier from the dereference
macros"). This remaining patch takes care of x86/uaccess following Dan's
suggestion [2].
[1] https://github.com/error27/smatch/commit/e53027a4e816a772403baafa83c09e4a94c1cb8f
[2] https://lore.kernel.org/all/CANiDSCuizbMt77XfrzGPMa3Biai5TF1vcs+C5qdhYoLrP=9b3g@xxxxxxxxxxxxxx/
---
Changes in v3:
- Drop rcu patch (already merged as commit 0381ade2ea82)
- x86/uaccess: use TYPEOF_NO_ADDRESS_SPACE() instead of TYPEOF_UNQUAL()
(thanks David Laight)
- x86/uaccess: update commit message to explain why TYPEOF_NO_ADDRESS_SPACE()
is used instead of TYPEOF_UNQUAL()
- Remove RCU maintainers and rcu@xxxxxxxxxxxxxxx from To/Cc
- Link to v2: https://lore.kernel.org/r/20260914-unqual-v2-0-60a1407a0cd4@xxxxxxxxxxxx
Changes in v2:
- Add TYPEOF_NO_ADDRESS_SPACE() in compiler.h
- x86: improve changelog
- Link to v1: https://lore.kernel.org/r/20260825-unqual-v1-0-7024fb81b4f9@xxxxxxxxxxxx
---
arch/x86/include/asm/uaccess.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index f4700ad6b5ec..66186a642f26 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -140,7 +140,7 @@ extern void __put_user_8(void);
int __ret_pu; \
void __user *__ptr_pu; \
register __typeof__(*(ptr)) __val_pu asm("%"_ASM_AX); \
- __typeof__(*(ptr)) __x = (x); /* eval x once */ \
+ TYPEOF_NO_ADDRESS_SPACE(*(ptr)) __x = (x); /* eval x once */ \
__typeof__(ptr) __ptr = (ptr); /* eval ptr once */ \
__chk_user_ptr(__ptr); \
__ptr_pu = __ptr; \
@@ -177,7 +177,7 @@ extern void __put_user_8(void);
#define __put_user_size(x, ptr, size, label) \
do { \
- __typeof__(*(ptr)) __x = (x); /* eval x once */ \
+ TYPEOF_NO_ADDRESS_SPACE(*(ptr)) __x = (x); /* eval x once */ \
__typeof__(ptr) __ptr = (ptr); /* eval ptr once */ \
__chk_user_ptr(__ptr); \
switch (size) { \
---
base-commit: 7e1392a42ea288d70a266f6553fe06f57f8647ea
change-id: 20260825-unqual-25d9ee74fd10
Best regards,
--
Ricardo Ribalda <ribalda@xxxxxxxxxxxx>