]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amdgpu: reject non-user addresses early in GEM_USERPTR ioctl
authorAmir Shetaia <Amir.Shetaia@amd.com>
Thu, 7 May 2026 17:24:55 +0000 (13:24 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 May 2026 16:08:47 +0000 (12:08 -0400)
amdgpu_gem_userptr_ioctl() currently accepts any value of args->addr
and only discovers an out-of-range pointer much later, inside
amdgpu_gem_object_create() and the HMM mirror registration path.
Userspace can drive that path with kernel-side virtual addresses;
the get_user_pages() layer rejects them, but only after the driver
has already allocated a GEM object and started wiring up notifier
state that then has to be torn down on failure.

Add an access_ok() guard at the top of the ioctl, right after the
existing page-alignment check and before flag validation, so any
address that does not lie within the calling task's user address
range is rejected with -EFAULT before any allocation occurs. No
legitimate ROCm/HSA userspace passes kernel-mode pointers through
this interface, so this is defense-in-depth rather than a behaviour
change for valid callers; -EFAULT matches the convention already
used by other uaccess-style rejections in the kernel.

Also add an explicit #include <linux/uaccess.h>; access_ok() is
otherwise only available transitively through other headers in
this translation unit.

Signed-off-by: Amir Shetaia <Amir.Shetaia@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 7a076df36397d780d7e4fb595287b4980451a7f5)

drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c

index 5376035d32fe8e56b5497e53536e3c942fddc303..23f2304ee7e091f2cd751c34c1873ff93b9985ea 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/pci.h>
 #include <linux/dma-buf.h>
 #include <linux/dma-fence-unwrap.h>
+#include <linux/uaccess.h>
 
 #include <drm/amdgpu_drm.h>
 #include <drm/drm_drv.h>
@@ -508,6 +509,9 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
        if (offset_in_page(args->addr | args->size))
                return -EINVAL;
 
+       if (!access_ok((void __user *)(uintptr_t)args->addr, args->size))
+               return -EFAULT;
+
        /* reject unknown flag values */
        if (args->flags & ~(AMDGPU_GEM_USERPTR_READONLY |
            AMDGPU_GEM_USERPTR_ANONONLY | AMDGPU_GEM_USERPTR_VALIDATE |