[RFC PATCH v1 7/9] x86: Add unsafe_copy_from_user()
"Christophe Leroy (CS GROUP)" <[email protected]> Mon, 27 Apr 2026 19:13:48 +0200
| Newsgroups | gmane.comp.freedesktop.amd-gfx,gmane.linux.ports.alpha,gmane.linux.kernel,gmane.linux.kernel.arc,gmane.linux.ports.arm.kernel,gmane.linux.ports.mips,gmane.linux.ports.ppc64.devel,gmane.comp.emulators.kvm.devel,gmane.linux.ports.riscv,gmane.linux.ports.sparc,gmane.linux.uml.devel,gmane.linux.kernel.efi,gmane.comp.video.dri.devel,gmane.comp.freedesktop.xorg.drivers.intel,gmane.linux.network,gmane.linux.kernel.wireless.general,gmane.linux.kernel.spi.devel,gmane.linux.drivers.video-input-infrastructure,gmane.linux.serial,gmane.linux.usb.general,gmane.comp.emulators.xen.devel,gmane.linux.file-systems,gmane.linux.kernel.bpf,gmane.linux.kernel.mm,gmane.linux.x25,gmane.linux.kernel.rust,gmane.linux.sound,gmane.linux.ports.hexagon,gmane.linux.ports.parisc,gmane.linux.ports.sh.devel,gmane.linux.kernel.cross-arch |
|---|---|
| Message-ID | <0ee46bb228d97163fbdc14f2a7c52b93d8bc34ce.1777306795.git.chleroy@kernel.org> |
At the time being, x86 and arm64 are missing unsafe_copy_from_user(). Add it. Signed-off-by: Christophe Leroy (CS GROUP) <[email protected]> --- 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