]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amdkfd: validate SVM ioctl nattr against buffer size
authorAlysa Liu <Alysa.Liu@amd.com>
Tue, 21 Apr 2026 14:18:28 +0000 (10:18 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 17 May 2026 15:16:31 +0000 (17:16 +0200)
commit 045e0ff208f0838a246c10204105126611b267a1 upstream.

Validate nattr field against the buffer size, preventing
out-of-bounds buffer access via user-controlled attribute count.

Reviewed-by: Amir Shetaia <Amir.Shetaia@amd.com>
Signed-off-by: Alysa Liu <Alysa.Liu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 5eca8bfdfa456c3304ca77523718fe24254c172f)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h

index 55ea5145a28accabb81d9321c1b5130809580779..f829d65a79b43e6c50a577dfdd888b12d0e466d0 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/err.h>
 #include <linux/fs.h>
 #include <linux/file.h>
+#include <linux/overflow.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
@@ -1695,6 +1696,16 @@ static int kfd_ioctl_smi_events(struct file *filep,
        return kfd_smi_event_open(pdd->dev, &args->anon_fd);
 }
 
+static int kfd_ioctl_svm_validate(void *kdata, unsigned int usize)
+{
+       struct kfd_ioctl_svm_args *args = kdata;
+       size_t expected = struct_size(args, attrs, args->nattr);
+
+       if (expected == SIZE_MAX || usize < expected)
+               return -EINVAL;
+       return 0;
+}
+
 #if IS_ENABLED(CONFIG_HSA_AMD_SVM)
 
 static int kfd_ioctl_set_xnack_mode(struct file *filep,
@@ -3209,7 +3220,11 @@ static int kfd_ioctl_create_process(struct file *filep, struct kfd_process *p, v
 
 #define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
        [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \
-                           .cmd_drv = 0, .name = #ioctl}
+                           .validate = NULL, .cmd_drv = 0, .name = #ioctl}
+
+#define AMDKFD_IOCTL_DEF_V(ioctl, _func, _validate, _flags) \
+       [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \
+                           .validate = _validate, .cmd_drv = 0, .name = #ioctl}
 
 /** Ioctl table */
 static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
@@ -3306,7 +3321,8 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
        AMDKFD_IOCTL_DEF(AMDKFD_IOC_SMI_EVENTS,
                        kfd_ioctl_smi_events, 0),
 
-       AMDKFD_IOCTL_DEF(AMDKFD_IOC_SVM, kfd_ioctl_svm, 0),
+       AMDKFD_IOCTL_DEF_V(AMDKFD_IOC_SVM, kfd_ioctl_svm,
+                          kfd_ioctl_svm_validate, 0),
 
        AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_XNACK_MODE,
                        kfd_ioctl_set_xnack_mode, 0),
@@ -3431,6 +3447,12 @@ static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
                memset(kdata, 0, usize);
        }
 
+       if (ioctl->validate) {
+               retcode = ioctl->validate(kdata, usize);
+               if (retcode)
+                       goto err_i1;
+       }
+
        retcode = func(filep, process, kdata);
 
        if (cmd & IOC_OUT)
index 5bcf4f1a89ffbc1657210a7c675f764039e91d9b..0d8e111e102524bf7480265ba323dae4bd0d46a4 100644 (file)
@@ -1047,10 +1047,13 @@ extern struct srcu_struct kfd_processes_srcu;
 typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p,
                                void *data);
 
+typedef int amdkfd_ioctl_validate_t(void *kdata, unsigned int usize);
+
 struct amdkfd_ioctl_desc {
        unsigned int cmd;
        int flags;
        amdkfd_ioctl_t *func;
+       amdkfd_ioctl_validate_t *validate;
        unsigned int cmd_drv;
        const char *name;
 };