]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ASoC: SOF: control: add size checks for ext_bytes control .put()
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Mon, 21 Sep 2020 11:08:12 +0000 (14:08 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 09:07:42 +0000 (10:07 +0100)
[ Upstream commit 2ca210112ad91880d2d5a3f85fecc838600afbce ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
sound/soc/sof/control.c

index 186eea105bb1514d3eaf2a96eea14a9fdaad9103..009938d45ddd979796db0fea33549fcd86c351e0 100644 (file)
@@ -298,6 +298,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
@@ -306,6 +310,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",