diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index bcc0d0ffe72ecfce9a4a0db0de15b1c606f9cd54..017d5101e7897e3ffddd5f918204c1030cf9c5eb 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -377,10 +377,10 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) struct wmfw_adsp2_id_hdr adsp2_id; struct wmfw_adsp1_alg_hdr *adsp1_alg; struct wmfw_adsp2_alg_hdr *adsp2_alg; - void *alg; + void *alg, *buf; const struct wm_adsp_region *mem; unsigned int pos, term; - size_t algs; + size_t algs, buf_size; __be32 val; int i, ret; @@ -411,6 +411,9 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) return ret; } + buf = &adsp1_id; + buf_size = sizeof(adsp1_id); + algs = be32_to_cpu(adsp1_id.algs); adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", be32_to_cpu(adsp1_id.fw.id), @@ -432,6 +435,9 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) return ret; } + buf = &adsp2_id; + buf_size = sizeof(adsp2_id); + algs = be32_to_cpu(adsp2_id.algs); adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", be32_to_cpu(adsp2_id.fw.id), @@ -454,6 +460,13 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp) return -EINVAL; } + if (algs > 1024) { + adsp_err(dsp, "Algorithm count %zx excessive\n", algs); + print_hex_dump_bytes(dev_name(dsp->dev), DUMP_PREFIX_OFFSET, + buf, buf_size); + return -EINVAL; + } + /* Read the terminator first to validate the length */ ret = regmap_raw_read(regmap, mem->base + term, &val, sizeof(val)); if (ret != 0) {