Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amdkfd: validate SVM ioctl nattr against buffer size

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

authored by

Alysa Liu and committed by
Alex Deucher
045e0ff2 47776ac1

+27 -2
+24 -2
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
··· 25 25 #include <linux/err.h> 26 26 #include <linux/fs.h> 27 27 #include <linux/file.h> 28 + #include <linux/overflow.h> 28 29 #include <linux/sched.h> 29 30 #include <linux/slab.h> 30 31 #include <linux/uaccess.h> ··· 1696 1695 return kfd_smi_event_open(pdd->dev, &args->anon_fd); 1697 1696 } 1698 1697 1698 + static int kfd_ioctl_svm_validate(void *kdata, unsigned int usize) 1699 + { 1700 + struct kfd_ioctl_svm_args *args = kdata; 1701 + size_t expected = struct_size(args, attrs, args->nattr); 1702 + 1703 + if (expected == SIZE_MAX || usize < expected) 1704 + return -EINVAL; 1705 + return 0; 1706 + } 1707 + 1699 1708 #if IS_ENABLED(CONFIG_HSA_AMD_SVM) 1700 1709 1701 1710 static int kfd_ioctl_set_xnack_mode(struct file *filep, ··· 3220 3209 3221 3210 #define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \ 3222 3211 [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \ 3223 - .cmd_drv = 0, .name = #ioctl} 3212 + .validate = NULL, .cmd_drv = 0, .name = #ioctl} 3213 + 3214 + #define AMDKFD_IOCTL_DEF_V(ioctl, _func, _validate, _flags) \ 3215 + [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \ 3216 + .validate = _validate, .cmd_drv = 0, .name = #ioctl} 3224 3217 3225 3218 /** Ioctl table */ 3226 3219 static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { ··· 3321 3306 AMDKFD_IOCTL_DEF(AMDKFD_IOC_SMI_EVENTS, 3322 3307 kfd_ioctl_smi_events, 0), 3323 3308 3324 - AMDKFD_IOCTL_DEF(AMDKFD_IOC_SVM, kfd_ioctl_svm, 0), 3309 + AMDKFD_IOCTL_DEF_V(AMDKFD_IOC_SVM, kfd_ioctl_svm, 3310 + kfd_ioctl_svm_validate, 0), 3325 3311 3326 3312 AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_XNACK_MODE, 3327 3313 kfd_ioctl_set_xnack_mode, 0), ··· 3445 3429 } 3446 3430 } else if (cmd & IOC_OUT) { 3447 3431 memset(kdata, 0, usize); 3432 + } 3433 + 3434 + if (ioctl->validate) { 3435 + retcode = ioctl->validate(kdata, usize); 3436 + if (retcode) 3437 + goto err_i1; 3448 3438 } 3449 3439 3450 3440 retcode = func(filep, process, kdata);
+3
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
··· 1047 1047 typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p, 1048 1048 void *data); 1049 1049 1050 + typedef int amdkfd_ioctl_validate_t(void *kdata, unsigned int usize); 1051 + 1050 1052 struct amdkfd_ioctl_desc { 1051 1053 unsigned int cmd; 1052 1054 int flags; 1053 1055 amdkfd_ioctl_t *func; 1056 + amdkfd_ioctl_validate_t *validate; 1054 1057 unsigned int cmd_drv; 1055 1058 const char *name; 1056 1059 };