[an error occurred while processing this directive]
[an error occurred while processing this directive]
|
|
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsq.1519831218.898207216@decadent.org.uk>
Date: Wed, 28 Feb 2018 15:20:18 +0000
From: Ben Hutchings <ben@...adent.org.uk>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC: akpm@...ux-foundation.org,
"Ben Hutchings" <ben.hutchings@...ethink.co.uk>,
"Charles Keepax" <ckeepax@...nsource.cirrus.com>,
"Mark Brown" <broonie@...nel.org>
Subject: [PATCH 3.16 080/254] ASoC: wm_adsp: Fix validation of firmware
and coeff lengths
3.16.55-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <ben.hutchings@...ethink.co.uk>
commit 50dd2ea8ef67a1617e0c0658bcbec4b9fb03b936 upstream.
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@...ethink.co.uk>
Acked-by: Charles Keepax <ckeepax@...nsource.cirrus.com>
Tested-by: Charles Keepax <ckeepax@...nsource.cirrus.com>
Signed-off-by: Mark Brown <broonie@...nel.org>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
sound/soc/codecs/wm_adsp.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -622,7 +622,7 @@ static int wm_adsp_load(struct wm_adsp *
le64_to_cpu(footer->timestamp));
while (pos < firmware->size &&
- pos - firmware->size > sizeof(*region)) {
+ sizeof(*region) < firmware->size - pos) {
region = (void *)&(firmware->data[pos]);
region_name = "Unknown";
reg = 0;
@@ -677,8 +677,8 @@ static int wm_adsp_load(struct wm_adsp *
regions, le32_to_cpu(region->len), offset,
region_name);
- if ((pos + le32_to_cpu(region->len) + sizeof(*region)) >
- firmware->size) {
+ if (le32_to_cpu(region->len) >
+ firmware->size - pos - sizeof(*region)) {
adsp_err(dsp,
"%s.%d: %s region len %d bytes exceeds file length %zu\n",
file, regions, region_name,
@@ -1248,7 +1248,7 @@ static int wm_adsp_load_coeff(struct wm_
blocks = 0;
while (pos < firmware->size &&
- pos - firmware->size > sizeof(*blk)) {
+ sizeof(*blk) < firmware->size - pos) {
blk = (void*)(&firmware->data[pos]);
type = le16_to_cpu(blk->type);
@@ -1328,8 +1328,8 @@ static int wm_adsp_load_coeff(struct wm_
}
if (reg) {
- if ((pos + le32_to_cpu(blk->len) + sizeof(*blk)) >
- firmware->size) {
+ if (le32_to_cpu(blk->len) >
+ firmware->size - pos - sizeof(*blk)) {
adsp_err(dsp,
"%s.%d: %s region len %d bytes exceeds file length %zu\n",
file, blocks, region_name,
Powered by blists - more mailing lists