Skip to contentSkip to conversation

Patch "ASoC: wm_adsp: Don't overrun firmware file buffer when reading region data" has been added to the 4.4-stable tree

PATCH [email protected] 1 participant 1 message Nov 28, 2017

Subsystems (4)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

ASoC: wm_adsp: Don't overrun firmware file buffer when reading region data

to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
asoc-wm_adsp-don-t-overrun-firmware-file-buffer-when-reading-region-data.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From foo@baz Tue Nov 28 10:56:34 CET 2017

From: Richard Fitzgerald <[email protected]>
Date: Tue, 20 Dec 2016 10:29:12 +0000
Subject: ASoC: wm_adsp: Don't overrun firmware file buffer when reading region data

From: Richard Fitzgerald <[email protected]>

[ Upstream commit 1cab2a84f470e15ecc8e5143bfe9398c6e888032 ]

Protect against corrupt firmware files by ensuring that the length we get for the data in a region actually lies within the available firmware file data buffer.

---
 sound/soc/codecs/wm_adsp.c |   25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)
sound/soc/codecs/wm_adsp.c +24 -1
@@ -1060,7 +1060,7 @@ static int wm_adsp_load(struct wm_adsp *
 	const struct wmfw_region *region;
 	const struct wm_adsp_region *mem;
 	const char *region_name;
-	char *file, *text;
+	char *file, *text = NULL;
 	struct wm_adsp_buf *buf;
 	unsigned int reg;
 	int regions = 0;
@@ -1221,10 +1221,21 @@ 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) {
+			adsp_err(dsp,
+				 "%s.%d: %s region len %d bytes exceeds file length %zu\n",
+				 file, regions, region_name,
+				 le32_to_cpu(region->len), firmware->size);
+			ret = -EINVAL;
+			goto out_fw;
+		}
+
 		if (text) {
 			memcpy(text, region->data, le32_to_cpu(region->len));
 			adsp_info(dsp, "%s: %s\n", file, text);
 			kfree(text);
+			text = NULL;
 		}
 
 		if (reg) {
@@ -1269,6 +1280,7 @@ out_fw:
 	regmap_async_complete(regmap);
 	wm_adsp_buf_free(&buf_list);
 	release_firmware(firmware);
+	kfree(text);
 out:
 	kfree(file);
 
@@ -1730,6 +1742,17 @@ static int wm_adsp_load_coeff(struct wm_
 		}
 
 		if (reg) {
+			if ((pos + le32_to_cpu(blk->len) + sizeof(*blk)) >
+			    firmware->size) {
+				adsp_err(dsp,
+					 "%s.%d: %s region len %d bytes exceeds file length %zu\n",
+					 file, blocks, region_name,
+					 le32_to_cpu(blk->len),
+					 firmware->size);
+				ret = -EINVAL;
+				goto out_fw;
+			}
+
 			buf = wm_adsp_buf_alloc(blk->data,
 						le32_to_cpu(blk->len),
 						&buf_list);

Patches currently in stable-queue which might be from [email protected] are

queue-4.4/asoc-wm_adsp-don-t-overrun-firmware-file-buffer-when-reading-region-data.patch