mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-18 13:36:07 +07:00
wil6210: validate wil_pmc_alloc parameters
num_descriptors and descriptor_size needs to be checked for: 1) not being negative values 2) no overflow occurs when these are multiplied together as done in wil_pmc_read. An overflow of two signed integers is undefined behavior. Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
bb6743f7c2
commit
1db226ffe1
@ -54,6 +54,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
|
||||
struct pmc_ctx *pmc = &wil->pmc;
|
||||
struct device *dev = wil_to_dev(wil);
|
||||
struct wmi_pmc_cmd pmc_cmd = {0};
|
||||
int last_cmd_err = -ENOMEM;
|
||||
|
||||
mutex_lock(&pmc->lock);
|
||||
|
||||
@ -62,6 +63,29 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
|
||||
wil_err(wil, "%s: ERROR pmc is already allocated\n", __func__);
|
||||
goto no_release_err;
|
||||
}
|
||||
if ((num_descriptors <= 0) || (descriptor_size <= 0)) {
|
||||
wil_err(wil,
|
||||
"Invalid params num_descriptors(%d), descriptor_size(%d)\n",
|
||||
num_descriptors, descriptor_size);
|
||||
last_cmd_err = -EINVAL;
|
||||
goto no_release_err;
|
||||
}
|
||||
|
||||
if (num_descriptors > (1 << WIL_RING_SIZE_ORDER_MAX)) {
|
||||
wil_err(wil,
|
||||
"num_descriptors(%d) exceeds max ring size %d\n",
|
||||
num_descriptors, 1 << WIL_RING_SIZE_ORDER_MAX);
|
||||
last_cmd_err = -EINVAL;
|
||||
goto no_release_err;
|
||||
}
|
||||
|
||||
if (num_descriptors > INT_MAX / descriptor_size) {
|
||||
wil_err(wil,
|
||||
"Overflow in num_descriptors(%d)*descriptor_size(%d)\n",
|
||||
num_descriptors, descriptor_size);
|
||||
last_cmd_err = -EINVAL;
|
||||
goto no_release_err;
|
||||
}
|
||||
|
||||
pmc->num_descriptors = num_descriptors;
|
||||
pmc->descriptor_size = descriptor_size;
|
||||
@ -189,7 +213,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
|
||||
pmc->descriptors = NULL;
|
||||
|
||||
no_release_err:
|
||||
pmc->last_cmd_status = -ENOMEM;
|
||||
pmc->last_cmd_status = last_cmd_err;
|
||||
mutex_unlock(&pmc->lock);
|
||||
}
|
||||
|
||||
@ -295,7 +319,7 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
|
||||
size_t retval = 0;
|
||||
unsigned long long idx;
|
||||
loff_t offset;
|
||||
size_t pmc_size = pmc->descriptor_size * pmc->num_descriptors;
|
||||
size_t pmc_size;
|
||||
|
||||
mutex_lock(&pmc->lock);
|
||||
|
||||
@ -306,6 +330,8 @@ ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
pmc_size = pmc->descriptor_size * pmc->num_descriptors;
|
||||
|
||||
wil_dbg_misc(wil,
|
||||
"%s: size %u, pos %lld\n",
|
||||
__func__, (unsigned)count, *f_pos);
|
||||
@ -345,7 +371,18 @@ loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence)
|
||||
loff_t newpos;
|
||||
struct wil6210_priv *wil = filp->private_data;
|
||||
struct pmc_ctx *pmc = &wil->pmc;
|
||||
size_t pmc_size = pmc->descriptor_size * pmc->num_descriptors;
|
||||
size_t pmc_size;
|
||||
|
||||
mutex_lock(&pmc->lock);
|
||||
|
||||
if (!wil_is_pmc_allocated(pmc)) {
|
||||
wil_err(wil, "error, pmc is not allocated!\n");
|
||||
pmc->last_cmd_status = -EPERM;
|
||||
mutex_unlock(&pmc->lock);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
pmc_size = pmc->descriptor_size * pmc->num_descriptors;
|
||||
|
||||
switch (whence) {
|
||||
case 0: /* SEEK_SET */
|
||||
@ -361,15 +398,21 @@ loff_t wil_pmc_llseek(struct file *filp, loff_t off, int whence)
|
||||
break;
|
||||
|
||||
default: /* can't happen */
|
||||
return -EINVAL;
|
||||
newpos = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (newpos < 0)
|
||||
return -EINVAL;
|
||||
if (newpos < 0) {
|
||||
newpos = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (newpos > pmc_size)
|
||||
newpos = pmc_size;
|
||||
|
||||
filp->f_pos = newpos;
|
||||
|
||||
out:
|
||||
mutex_unlock(&pmc->lock);
|
||||
|
||||
return newpos;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user