From aa62ae87dd18a2ca3b2aeb07a6014a08f686aa3d Mon Sep 17 00:00:00 2001 From: Tony Hutter Date: Thu, 23 Apr 2026 10:52:19 -0700 Subject: [PATCH] Fix 'kernel BUG at mm/usercopy.c' Fix a bug where an cgroup-OOM-killed process can cause a panic: usercopy: Kernel memory exposure attempt detected from vmalloc (offset 1007584, size 217120)! kernel BUG at mm/usercopy.c:102! This was caused by zfs_uiomove() not correctly returning EFAULT for short copies. Reviewed-by: Brian Behlendorf Signed-off-by: Tony Hutter Closes #15918 Closes #18408 --- module/os/linux/zfs/zfs_uio.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/module/os/linux/zfs/zfs_uio.c b/module/os/linux/zfs/zfs_uio.c index 8f9b16199..bfce9e6b5 100644 --- a/module/os/linux/zfs/zfs_uio.c +++ b/module/os/linux/zfs/zfs_uio.c @@ -234,6 +234,8 @@ zfs_uiomove_iter(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio, boolean_t revert) { size_t cnt = MIN(n, uio->uio_resid); + size_t oldcnt = cnt; + int error = 0; if (rw == UIO_READ) cnt = copy_to_iter(p, cnt, uio->uio_iter); @@ -249,16 +251,21 @@ zfs_uiomove_iter(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio, return (EFAULT); /* - * Revert advancing the uio_iter. This is set by zfs_uiocopy() - * to avoid consuming the uio and its iov_iter structure. + * When revert is set this is a zfs_uiocopy() which should not + * consume the uio and its iov_iter structure. Otherwise, it's + * a zfs_uiomove() which is expected to update the uio. Partial + * copies are allowed for both copy and move but EFAULT should + * be returned for zfs_uiomove(). */ if (revert) iov_iter_revert(uio->uio_iter, cnt); + else if (cnt != oldcnt) + error = EFAULT; uio->uio_resid -= cnt; uio->uio_loffset += cnt; - return (0); + return (error); } int