diff options
author | Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> | 2020-09-21 14:08:12 +0300 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2020-09-21 23:14:47 +0100 |
commit | 2ca210112ad91880d2d5a3f85fecc838600afbce (patch) | |
tree | 852ccdb0927afa5c5f978cbd3c95fd8cc04d9df0 /sound/soc/sof/control.c | |
parent | ec5a97624a8de4f44b090cf53bd48c05458e0b17 (diff) | |
download | lwn-2ca210112ad91880d2d5a3f85fecc838600afbce.tar.gz lwn-2ca210112ad91880d2d5a3f85fecc838600afbce.zip |
ASoC: SOF: control: add size checks for ext_bytes control .put()
Make sure the TLV header and size are consistent before copying from
userspace.
Fixes: c3078f5397046 ('ASoC: SOF: Add Sound Open Firmware KControl support')
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20200921110814.2910477-4-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/control.c')
-rw-r--r-- | sound/soc/sof/control.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/sound/soc/sof/control.c b/sound/soc/sof/control.c index 9465611156d5..0352d2b61358 100644 --- a/sound/soc/sof/control.c +++ b/sound/soc/sof/control.c @@ -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 *)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 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))) 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 */ if (header.length > be->max) { dev_err_ratelimited(scomp->dev, "error: Bytes data size %d exceeds max %d.\n", |