Skip to content

Commit 681b223

Browse files
Richard Fitzgeraldgregkh
authored andcommitted
ASoC: wm_adsp: Don't overrun firmware file buffer when reading region data
[ 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. Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com> Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent b63209c commit 681b223

1 file changed

Lines changed: 24 additions & 1 deletion

File tree

sound/soc/codecs/wm_adsp.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
10601060
const struct wmfw_region *region;
10611061
const struct wm_adsp_region *mem;
10621062
const char *region_name;
1063-
char *file, *text;
1063+
char *file, *text = NULL;
10641064
struct wm_adsp_buf *buf;
10651065
unsigned int reg;
10661066
int regions = 0;
@@ -1221,10 +1221,21 @@ static int wm_adsp_load(struct wm_adsp *dsp)
12211221
regions, le32_to_cpu(region->len), offset,
12221222
region_name);
12231223

1224+
if ((pos + le32_to_cpu(region->len) + sizeof(*region)) >
1225+
firmware->size) {
1226+
adsp_err(dsp,
1227+
"%s.%d: %s region len %d bytes exceeds file length %zu\n",
1228+
file, regions, region_name,
1229+
le32_to_cpu(region->len), firmware->size);
1230+
ret = -EINVAL;
1231+
goto out_fw;
1232+
}
1233+
12241234
if (text) {
12251235
memcpy(text, region->data, le32_to_cpu(region->len));
12261236
adsp_info(dsp, "%s: %s\n", file, text);
12271237
kfree(text);
1238+
text = NULL;
12281239
}
12291240

12301241
if (reg) {
@@ -1269,6 +1280,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
12691280
regmap_async_complete(regmap);
12701281
wm_adsp_buf_free(&buf_list);
12711282
release_firmware(firmware);
1283+
kfree(text);
12721284
out:
12731285
kfree(file);
12741286

@@ -1730,6 +1742,17 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
17301742
}
17311743

17321744
if (reg) {
1745+
if ((pos + le32_to_cpu(blk->len) + sizeof(*blk)) >
1746+
firmware->size) {
1747+
adsp_err(dsp,
1748+
"%s.%d: %s region len %d bytes exceeds file length %zu\n",
1749+
file, blocks, region_name,
1750+
le32_to_cpu(blk->len),
1751+
firmware->size);
1752+
ret = -EINVAL;
1753+
goto out_fw;
1754+
}
1755+
17331756
buf = wm_adsp_buf_alloc(blk->data,
17341757
le32_to_cpu(blk->len),
17351758
&buf_list);

0 commit comments

Comments
 (0)