[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC PATCH v1 7/9] x86: Add unsafe_copy_from_user()
- To: Yury Norov <ynorov@xxxxxxxxxx>
- From: "Christophe Leroy (CS GROUP)" <chleroy@xxxxxxxxxx>
- Date: Mon, 27 Apr 2026 20:20:38 +0200
- Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=k20201202 header.d=kernel.org header.i="@kernel.org" header.h="Date:Subject:To:Cc:References:From:In-Reply-To"
- Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>, Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>, David Laight <david.laight.linux@xxxxxxxxx>, Thomas Gleixner <tglx@xxxxxxxxxxxxx>, linux-alpha@xxxxxxxxxxxxxxx, linux-kernel@xxxxxxxxxxxxxxx, linux-snps-arc@xxxxxxxxxxxxxxxxxxx, linux-arm-kernel@xxxxxxxxxxxxxxxxxxx, linux-mips@xxxxxxxxxxxxxxx, linuxppc-dev@xxxxxxxxxxxxxxxx, kvm@xxxxxxxxxxxxxxx, linux-riscv@xxxxxxxxxxxxxxxxxxx, linux-s390@xxxxxxxxxxxxxxx, sparclinux@xxxxxxxxxxxxxxx, linux-um@xxxxxxxxxxxxxxxxxxx, dmaengine@xxxxxxxxxxxxxxx, linux-efi@xxxxxxxxxxxxxxx, linux-fsi@xxxxxxxxxxxxxxxx, amd-gfx@xxxxxxxxxxxxxxxxxxxxx, dri-devel@xxxxxxxxxxxxxxxxxxxxx, intel-gfx@xxxxxxxxxxxxxxxxxxxxx, linux-wpan@xxxxxxxxxxxxxxx, netdev@xxxxxxxxxxxxxxx, linux-wireless@xxxxxxxxxxxxxxx, linux-spi@xxxxxxxxxxxxxxx, linux-media@xxxxxxxxxxxxxxx, linux-staging@xxxxxxxxxxxxxxx, linux-serial@xxxxxxxxxxxxxxx, linux-usb@xxxxxxxxxxxxxxx, xen-devel@xxxxxxxxxxxxxxxxxxxx, linux-fsdevel@xxxxxxxxxxxxxxx, ocfs2-devel@xxxxxxxxxxxxxxx, bpf@xxxxxxxxxxxxxxx, kasan-dev@xxxxxxxxxxxxxxxx, linux-mm@xxxxxxxxx, linux-x25@xxxxxxxxxxxxxxx, rust-for-linux@xxxxxxxxxxxxxxx, linux-sound@xxxxxxxxxxxxxxx, sound-open-firmware@xxxxxxxxxxxxxxxx, linux-csky@xxxxxxxxxxxxxxx, linux-hexagon@xxxxxxxxxxxxxxx, loongarch@xxxxxxxxxxxxxxx, linux-m68k@xxxxxxxxxxxxxxxxxxxx, linux-openrisc@xxxxxxxxxxxxxxx, linux-parisc@xxxxxxxxxxxxxxx, linux-sh@xxxxxxxxxxxxxxx, linux-arch@xxxxxxxxxxxxxxx
- Delivery-date: Mon, 27 Apr 2026 18:21:54 +0000
- List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
Le 27/04/2026 à 19:58, Yury Norov a écrit :
On Mon, Apr 27, 2026 at 07:13:48PM +0200, Christophe Leroy (CS GROUP) wrote:
At the time being, x86 and arm64 are missing unsafe_copy_from_user().
No, they don't. They (should) rely on a generic implementation from
linux/uaccess.h, like every other arch, except for PPC and RISCV.
But they #define arch_unsafe_get_user, and the unsafe_copy_from_user()
becomes undefined conditionally on that.
So please, fix that bug instead of introducing another arch flavor.
We'd always choose generic version, unless there's strong evidence
that arch one is better.
But they both implement the exact same unsafe_copy_to_user(). What is
the difference here ?
Should that function become generic too ?
Christophe
Thanks,
Yury
Add it.
Signed-off-by: Christophe Leroy (CS GROUP) <chleroy@xxxxxxxxxx>
---
arch/x86/include/asm/uaccess.h | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 3a0dd3c2b233..10c458ffa399 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -598,7 +598,7 @@ _label:
\
* We want the unsafe accessors to always be inlined and use
* the error labels - thus the macro games.
*/
-#define unsafe_copy_loop(dst, src, len, type, label)
\
+#define unsafe_put_loop(dst, src, len, type, label)
\
while (len >= sizeof(type)) {
\
unsafe_put_user(*(type *)(src),(type __user *)(dst),label);
\
dst += sizeof(type);
\
@@ -611,10 +611,29 @@ do {
\
char __user *__ucu_dst = (_dst); \
const char *__ucu_src = (_src); \
size_t __ucu_len = (_len); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label); \
- unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label); \
+ unsafe_put_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label); \
+ unsafe_put_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label); \
+ unsafe_put_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label); \
+ unsafe_put_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label); \
+} while (0)
+
+#define unsafe_get_loop(dst, src, len, type, label)
\
+ while (len >= sizeof(type)) {
\
+ unsafe_get_user(*(type __user *)(src),(type *)(dst),label);
\
+ dst += sizeof(type);
\
+ src += sizeof(type);
\
+ len -= sizeof(type);
\
+ }
+
+#define unsafe_copy_from_user(_dst,_src,_len,label) \
+do { \
+ char *__ucu_dst = (_dst); \
+ const char __user *__ucu_src = (_src); \
+ size_t __ucu_len = (_len); \
+ unsafe_get_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label); \
+ unsafe_get_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label); \
+ unsafe_get_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label); \
+ unsafe_get_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label); \
} while (0)
#ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
--
2.49.0
|