Merge series "ASoC: SOF: fix kcontrol size checks" from Kai Vehmanen <kai.vehmanen@linux.intel.com>:
Series that fixes checks for 'size' in kcontrol get/put ext_bytes methods for SOF. The gaps in these checks were discovered via cppcheck warnings on unused variable values. Pierre-Louis Bossart (5): ASoC: SOF: control: fix size checks for ext_bytes control .get() ASoC: SOF: control: fix size checks for volatile ext_bytes control .get() ASoC: SOF: control: add size checks for ext_bytes control .put() ASoC: SOF: control: remove const in sizeof() ASoC: SOF: topology: remove const in sizeof() sound/soc/sof/control.c | 53 +++++++++++++++++++++++++++++++--------- sound/soc/sof/topology.c | 2 +- 2 files changed, 43 insertions(+), 12 deletions(-) -- 2.27.0
This commit is contained in:
Коммит
376dd57d88
|
@ -300,6 +300,10 @@ int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
|
||||||
const struct snd_ctl_tlv __user *tlvd =
|
const struct snd_ctl_tlv __user *tlvd =
|
||||||
(const struct snd_ctl_tlv __user *)binary_data;
|
(const struct snd_ctl_tlv __user *)binary_data;
|
||||||
|
|
||||||
|
/* make sure we have at least a header */
|
||||||
|
if (size < sizeof(struct snd_ctl_tlv))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The beginning of bytes data contains a header from where
|
* The beginning of bytes data contains a header from where
|
||||||
* the length (as bytes) is needed to know the correct copy
|
* the length (as bytes) is needed to know the correct copy
|
||||||
|
@ -308,6 +312,13 @@ int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
|
||||||
if (copy_from_user(&header, tlvd, sizeof(const struct snd_ctl_tlv)))
|
if (copy_from_user(&header, tlvd, sizeof(const struct snd_ctl_tlv)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
/* make sure TLV info is consistent */
|
||||||
|
if (header.length + sizeof(struct snd_ctl_tlv) > size) {
|
||||||
|
dev_err_ratelimited(scomp->dev, "error: inconsistent TLV, data %d + header %zu > %d\n",
|
||||||
|
header.length, sizeof(struct snd_ctl_tlv), size);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* be->max is coming from topology */
|
/* be->max is coming from topology */
|
||||||
if (header.length > be->max) {
|
if (header.length > be->max) {
|
||||||
dev_err_ratelimited(scomp->dev, "error: Bytes data size %d exceeds max %d.\n",
|
dev_err_ratelimited(scomp->dev, "error: Bytes data size %d exceeds max %d.\n",
|
||||||
|
@ -369,6 +380,14 @@ int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int _
|
||||||
int ret;
|
int ret;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decrement the limit by ext bytes header size to
|
||||||
|
* ensure the user space buffer is not exceeded.
|
||||||
|
*/
|
||||||
|
if (size < sizeof(struct snd_ctl_tlv))
|
||||||
|
return -ENOSPC;
|
||||||
|
size -= sizeof(struct snd_ctl_tlv);
|
||||||
|
|
||||||
ret = pm_runtime_get_sync(scomp->dev);
|
ret = pm_runtime_get_sync(scomp->dev);
|
||||||
if (ret < 0 && ret != -EACCES) {
|
if (ret < 0 && ret != -EACCES) {
|
||||||
dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to resume %d\n", ret);
|
dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to resume %d\n", ret);
|
||||||
|
@ -396,6 +415,12 @@ int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int _
|
||||||
|
|
||||||
data_size = cdata->data->size + sizeof(const struct sof_abi_hdr);
|
data_size = cdata->data->size + sizeof(const struct sof_abi_hdr);
|
||||||
|
|
||||||
|
/* make sure we don't exceed size provided by user space for data */
|
||||||
|
if (data_size > size) {
|
||||||
|
ret = -ENOSPC;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
header.numid = scontrol->cmd;
|
header.numid = scontrol->cmd;
|
||||||
header.length = data_size;
|
header.length = data_size;
|
||||||
if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv))) {
|
if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv))) {
|
||||||
|
@ -432,7 +457,9 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
|
||||||
* Decrement the limit by ext bytes header size to
|
* Decrement the limit by ext bytes header size to
|
||||||
* ensure the user space buffer is not exceeded.
|
* ensure the user space buffer is not exceeded.
|
||||||
*/
|
*/
|
||||||
size -= sizeof(const struct snd_ctl_tlv);
|
if (size < sizeof(struct snd_ctl_tlv))
|
||||||
|
return -ENOSPC;
|
||||||
|
size -= sizeof(struct snd_ctl_tlv);
|
||||||
|
|
||||||
/* set the ABI header values */
|
/* set the ABI header values */
|
||||||
cdata->data->magic = SOF_ABI_MAGIC;
|
cdata->data->magic = SOF_ABI_MAGIC;
|
||||||
|
@ -448,6 +475,10 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
|
||||||
|
|
||||||
data_size = cdata->data->size + sizeof(const struct sof_abi_hdr);
|
data_size = cdata->data->size + sizeof(const struct sof_abi_hdr);
|
||||||
|
|
||||||
|
/* make sure we don't exceed size provided by user space for data */
|
||||||
|
if (data_size > size)
|
||||||
|
return -ENOSPC;
|
||||||
|
|
||||||
header.numid = scontrol->cmd;
|
header.numid = scontrol->cmd;
|
||||||
header.length = data_size;
|
header.length = data_size;
|
||||||
if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv)))
|
if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv)))
|
||||||
|
|
Загрузка…
Ссылка в новой задаче