mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
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>
This commit is contained in:
parent
793aebf57d
commit
5eca8bfdfa
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1046,10 +1046,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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user