Skip to content

Commit 91c6dc5

Browse files
amd-alysaliugregkh
authored andcommitted
drm/amdkfd: validate SVM ioctl nattr against buffer size
commit 045e0ff 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 5eca8bf) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 6b99259 commit 91c6dc5

2 files changed

Lines changed: 27 additions & 2 deletions

File tree

drivers/gpu/drm/amd/amdkfd/kfd_chardev.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <linux/err.h>
2727
#include <linux/fs.h>
2828
#include <linux/file.h>
29+
#include <linux/overflow.h>
2930
#include <linux/sched.h>
3031
#include <linux/slab.h>
3132
#include <linux/uaccess.h>
@@ -1705,6 +1706,16 @@ static int kfd_ioctl_smi_events(struct file *filep,
17051706
return kfd_smi_event_open(pdd->dev, &args->anon_fd);
17061707
}
17071708

1709+
static int kfd_ioctl_svm_validate(void *kdata, unsigned int usize)
1710+
{
1711+
struct kfd_ioctl_svm_args *args = kdata;
1712+
size_t expected = struct_size(args, attrs, args->nattr);
1713+
1714+
if (expected == SIZE_MAX || usize < expected)
1715+
return -EINVAL;
1716+
return 0;
1717+
}
1718+
17081719
#if IS_ENABLED(CONFIG_HSA_AMD_SVM)
17091720

17101721
static int kfd_ioctl_set_xnack_mode(struct file *filep,
@@ -3128,7 +3139,11 @@ static int kfd_ioctl_set_debug_trap(struct file *filep, struct kfd_process *p, v
31283139

31293140
#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
31303141
[_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \
3131-
.cmd_drv = 0, .name = #ioctl}
3142+
.validate = NULL, .cmd_drv = 0, .name = #ioctl}
3143+
3144+
#define AMDKFD_IOCTL_DEF_V(ioctl, _func, _validate, _flags) \
3145+
[_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \
3146+
.validate = _validate, .cmd_drv = 0, .name = #ioctl}
31323147

31333148
/** Ioctl table */
31343149
static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
@@ -3225,7 +3240,8 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
32253240
AMDKFD_IOCTL_DEF(AMDKFD_IOC_SMI_EVENTS,
32263241
kfd_ioctl_smi_events, 0),
32273242

3228-
AMDKFD_IOCTL_DEF(AMDKFD_IOC_SVM, kfd_ioctl_svm, 0),
3243+
AMDKFD_IOCTL_DEF_V(AMDKFD_IOC_SVM, kfd_ioctl_svm,
3244+
kfd_ioctl_svm_validate, 0),
32293245

32303246
AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_XNACK_MODE,
32313247
kfd_ioctl_set_xnack_mode, 0),
@@ -3347,6 +3363,12 @@ static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
33473363
memset(kdata, 0, usize);
33483364
}
33493365

3366+
if (ioctl->validate) {
3367+
retcode = ioctl->validate(kdata, usize);
3368+
if (retcode)
3369+
goto err_i1;
3370+
}
3371+
33503372
retcode = func(filep, process, kdata);
33513373

33523374
if (cmd & IOC_OUT)

drivers/gpu/drm/amd/amdkfd/kfd_priv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,10 +1006,13 @@ extern struct srcu_struct kfd_processes_srcu;
10061006
typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p,
10071007
void *data);
10081008

1009+
typedef int amdkfd_ioctl_validate_t(void *kdata, unsigned int usize);
1010+
10091011
struct amdkfd_ioctl_desc {
10101012
unsigned int cmd;
10111013
int flags;
10121014
amdkfd_ioctl_t *func;
1015+
amdkfd_ioctl_validate_t *validate;
10131016
unsigned int cmd_drv;
10141017
const char *name;
10151018
};

0 commit comments

Comments
 (0)