aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <ben.hutchings@codethink.co.uk>2017-12-08 11:15:20 -0500
committerMark Brown <broonie@kernel.org>2017-12-08 12:17:35 -0500
commit50dd2ea8ef67a1617e0c0658bcbec4b9fb03b936 (patch)
tree9d15f6975338271b7b43f8ce32d60daaf3aed018
parent4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323 (diff)
ASoC: wm_adsp: Fix validation of firmware and coeff lengths
The checks for whether another region/block header could be present are subtracting the size from the current offset. Obviously we should instead subtract the offset from the size. The checks for whether the region/block data fit in the file are adding the data size to the current offset and header size, without checking for integer overflow. Rearrange these so that overflow is impossible. Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com> Tested-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Mark Brown <broonie@kernel.org> Cc: stable@vger.kernel.org
-rw-r--r--sound/soc/codecs/wm_adsp.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 65c059b5ffd7..66e32f5d2917 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -1733,7 +1733,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
1733 le64_to_cpu(footer->timestamp)); 1733 le64_to_cpu(footer->timestamp));
1734 1734
1735 while (pos < firmware->size && 1735 while (pos < firmware->size &&
1736 pos - firmware->size > sizeof(*region)) { 1736 sizeof(*region) < firmware->size - pos) {
1737 region = (void *)&(firmware->data[pos]); 1737 region = (void *)&(firmware->data[pos]);
1738 region_name = "Unknown"; 1738 region_name = "Unknown";
1739 reg = 0; 1739 reg = 0;
@@ -1782,8 +1782,8 @@ static int wm_adsp_load(struct wm_adsp *dsp)
1782 regions, le32_to_cpu(region->len), offset, 1782 regions, le32_to_cpu(region->len), offset,
1783 region_name); 1783 region_name);
1784 1784
1785 if ((pos + le32_to_cpu(region->len) + sizeof(*region)) > 1785 if (le32_to_cpu(region->len) >
1786 firmware->size) { 1786 firmware->size - pos - sizeof(*region)) {
1787 adsp_err(dsp, 1787 adsp_err(dsp,
1788 "%s.%d: %s region len %d bytes exceeds file length %zu\n", 1788 "%s.%d: %s region len %d bytes exceeds file length %zu\n",
1789 file, regions, region_name, 1789 file, regions, region_name,
@@ -2253,7 +2253,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
2253 2253
2254 blocks = 0; 2254 blocks = 0;
2255 while (pos < firmware->size && 2255 while (pos < firmware->size &&
2256 pos - firmware->size > sizeof(*blk)) { 2256 sizeof(*blk) < firmware->size - pos) {
2257 blk = (void *)(&firmware->data[pos]); 2257 blk = (void *)(&firmware->data[pos]);
2258 2258
2259 type = le16_to_cpu(blk->type); 2259 type = le16_to_cpu(blk->type);
@@ -2327,8 +2327,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
2327 } 2327 }
2328 2328
2329 if (reg) { 2329 if (reg) {
2330 if ((pos + le32_to_cpu(blk->len) + sizeof(*blk)) > 2330 if (le32_to_cpu(blk->len) >
2331 firmware->size) { 2331 firmware->size - pos - sizeof(*blk)) {
2332 adsp_err(dsp, 2332 adsp_err(dsp,
2333 "%s.%d: %s region len %d bytes exceeds file length %zu\n", 2333 "%s.%d: %s region len %d bytes exceeds file length %zu\n",
2334 file, blocks, region_name, 2334 file, blocks, region_name,