From e21fb64a8c4aecae31ec63f994423ac944705c3e Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Fri, 23 Oct 2026 18:13:10 +0100 Subject: [PATCH 1/7] ASoC: qcom: audioreach: fix module cfg blob size handling audioreach_get_module_priv_data() passes mod_array->size, a byte count, as the element count of the __le32 data[] flex array. The allocation and the copy are four times too large, and the memcpy() can read past the end of the topology firmware buffer. The size is also never checked against the private data it must lie within, and a zero size makes the loop spin forever. Convert the size to a word count, bound the blob by the remaining private data and reject a zero size. Also check the returned pointer before storing it in mod->data, as an error pointer there is dereferenced when the graph is opened. Fixes: c7ed4c2debfd ("ASoC: qcom: audioreach: add support for static calibration") Cc: stable@vger.kernel.org Signed-off-by: Ravi Hothi Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20261023171316.819857-2-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/topology.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/sound/soc/qcom/qdsp6/topology.c b/sound/soc/qcom/qdsp6/topology.c index faafbc5c0ad0..612d8f03e6e9 100644 --- a/sound/soc/qcom/qdsp6/topology.c +++ b/sound/soc/qcom/qdsp6/topology.c @@ -312,22 +312,37 @@ audioreach_get_module_priv_data(const struct snd_soc_tplg_private *private) for (sz = 0; sz < le32_to_cpu(private->size); ) { const struct snd_soc_tplg_vendor_array *mod_array; + u32 array_size; mod_array = (struct snd_soc_tplg_vendor_array *)((u8 *)private->array + sz); + array_size = le32_to_cpu(mod_array->size); + if (le32_to_cpu(mod_array->type) == SND_SOC_AR_TPLG_MODULE_CFG_TYPE) { struct audioreach_module_priv_data *pdata; + u32 nwords; - pdata = kzalloc_flex(*pdata, data, - le32_to_cpu(mod_array->size)); + /* size is the byte count of the __le32 data[] */ + nwords = array_size / sizeof(__le32); + + /* the blob must lie within the private data */ + if (sizeof(*pdata) + (u64)array_size > + le32_to_cpu(private->size) - sz) + return ERR_PTR(-EINVAL); + + pdata = kzalloc_flex(*pdata, data, nwords); if (!pdata) return ERR_PTR(-ENOMEM); - memcpy(pdata, ((u8 *)private->data + sz), struct_size(pdata, data, - le32_to_cpu(mod_array->size))); + memcpy(pdata, ((u8 *)private->data + sz), + struct_size(pdata, data, nwords)); return pdata; } - sz = sz + le32_to_cpu(mod_array->size); + /* a zero size would never advance the walk */ + if (!array_size) + return ERR_PTR(-EINVAL); + + sz = sz + array_size; } return NULL; @@ -611,6 +626,12 @@ static int audioreach_widget_load_module_common(struct snd_soc_component *compon return mod ? PTR_ERR(mod) : -ENODEV; mod->data = audioreach_get_module_priv_data(&tplg_w->priv); + if (IS_ERR(mod->data)) { + int rc = PTR_ERR(mod->data); + + mod->data = NULL; + return rc; + } dobj = &w->dobj; dobj->private = mod; From 00535515e3c14fbee20de4a1aa61cfb3390f0f50 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 23 Oct 2026 18:13:11 +0100 Subject: [PATCH 2/7] ASoC: codecs: wsa884x: Accept temperatures across the full trim range wsa884x_get_temp() rejects any reading outside 5..45 degC with -EAGAIN. A speaker that has been playing, or sits in a warm laptop, easily runs above 45 degC, so its temperature becomes unreadable when it matters. The check only needs to drop bogus conversions, such as the all-zero reading before the PA is first enabled. Bound it by the -10..150 degC two-point trim range instead. Fixes: 6b99dc62d940 ("ASoC: codecs: wsa884x: Implement temperature reading and hwmon") Cc: stable@vger.kernel.org Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20261023171316.819857-3-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/wsa884x.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c index a367c94bfb4d..f0857c0588d5 100644 --- a/sound/soc/codecs/wsa884x.c +++ b/sound/soc/codecs/wsa884x.c @@ -720,10 +720,11 @@ /* * Device will report senseless data in many cases, so discard any measurements - * outside of valid range. + * outside of the two-point trim range. Do not narrow this to ambient: a + * speaker that has been playing easily runs well above 45 degC. */ -#define WSA884X_LOW_TEMP_THRESHOLD 5 -#define WSA884X_HIGH_TEMP_THRESHOLD 45 +#define WSA884X_LOW_TEMP_THRESHOLD WSA884X_T1_TEMP +#define WSA884X_HIGH_TEMP_THRESHOLD WSA884X_T2_TEMP struct wsa884x_priv { struct regmap *regmap; @@ -1929,8 +1930,8 @@ static int wsa884x_get_temp(struct wsa884x_priv *wsa884x, long *temp) dev_dbg(wsa884x->dev, "Measured temp %ld (dmeas=%d, d1=%d, d2=%d)\n", val, dmeas, d1, d2); - if ((val > WSA884X_LOW_TEMP_THRESHOLD) && - (val < WSA884X_HIGH_TEMP_THRESHOLD)) { + if (val >= WSA884X_LOW_TEMP_THRESHOLD && + val <= WSA884X_HIGH_TEMP_THRESHOLD) { wsa884x->temperature = val; *temp = val * 1000; ret = 0; From 6a55cf0d9dd2e2493a5030a4f7b0413d31165e45 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 23 Oct 2026 18:13:12 +0100 Subject: [PATCH 3/7] ASoC: codecs: wsa883x: Accept temperatures across the full trim range wsa883x_get_temp() rejects any reading outside 5..45 degC with -EAGAIN, so a speaker that has been playing, or sits in a warm chassis, becomes unreadable above 45 degC. Bound the check by the -10..150 degC two-point trim range instead, and use inclusive comparisons, as in_range() excludes the upper bound. Fixes: a02c42d41af7 ("ASoC: codecs: wsa883x: Implement temperature reading and hwmon") Cc: stable@vger.kernel.org Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20261023171316.819857-4-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/wsa883x.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index 442cf9f3eaac..ccd4404c1644 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -456,10 +456,11 @@ /* * Device will report senseless data in many cases, so discard any measurements - * outside of valid range. + * outside of the two-point trim range. Do not narrow this to ambient: a + * speaker that has been playing easily runs well above 45 degC. */ -#define WSA883X_LOW_TEMP_THRESHOLD 5 -#define WSA883X_HIGH_TEMP_THRESHOLD 45 +#define WSA883X_LOW_TEMP_THRESHOLD WSA883X_T1_TEMP +#define WSA883X_HIGH_TEMP_THRESHOLD WSA883X_T2_TEMP struct wsa883x_priv { struct regmap *regmap; @@ -1430,7 +1431,7 @@ static int wsa883x_get_temp(struct wsa883x_priv *wsa883x, long *temp) unsigned int dmeas_msb = 0, dmeas_lsb = 0; int d1, d2, dmeas; unsigned int mask; - int ret, range; + int ret; long val; guard(mutex)(&wsa883x->sp_lock); @@ -1493,8 +1494,8 @@ static int wsa883x_get_temp(struct wsa883x_priv *wsa883x, long *temp) } val = WSA883X_T1_TEMP + (((dmeas - d1) * (WSA883X_T2_TEMP - WSA883X_T1_TEMP)) / (d2 - d1)); - range = WSA883X_HIGH_TEMP_THRESHOLD - WSA883X_LOW_TEMP_THRESHOLD; - if (in_range(val, WSA883X_LOW_TEMP_THRESHOLD, range)) { + if (val >= WSA883X_LOW_TEMP_THRESHOLD && + val <= WSA883X_HIGH_TEMP_THRESHOLD) { wsa883x->temperature = val; *temp = val * 1000; ret = 0; From 54c121eaeed8ee7751935db8100b6b5c57124db9 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 23 Oct 2026 18:13:13 +0100 Subject: [PATCH 4/7] ASoC: codecs: wsa884x: disable runtime PM on unbind Probe enables runtime PM but nothing disables it on unbind. The pending autosuspend then runs wsa884x_runtime_suspend() after the devm-managed regmap is freed, and dereferences NULL: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020 pc : regcache_cache_only+0x18/0x80 lr : wsa884x_runtime_suspend+0x24/0x40 [snd_soc_wsa884x] Use devm_pm_runtime_enable() so runtime PM is disabled before the regmap is freed. Fixes: aa21a7d4f68a ("ASoC: codecs: wsa884x: Add WSA884x family of speakers") Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20261023171316.819857-5-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/wsa884x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c index f0857c0588d5..3c008224d32e 100644 --- a/sound/soc/codecs/wsa884x.c +++ b/sound/soc/codecs/wsa884x.c @@ -2125,7 +2125,9 @@ static int wsa884x_probe(struct sdw_slave *pdev, pm_runtime_use_autosuspend(dev); pm_runtime_mark_last_busy(dev); pm_runtime_set_active(dev); - pm_runtime_enable(dev); + ret = devm_pm_runtime_enable(dev); + if (ret) + return ret; return devm_snd_soc_register_component(dev, &wsa884x_component_drv, From ea63182d71956dc33c6f08dc4171f1052f8409a9 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 23 Oct 2026 18:13:14 +0100 Subject: [PATCH 5/7] ASoC: codecs: wsa883x: disable runtime PM on unbind Probe enables runtime PM but nothing disables it on unbind, or when registering the component fails. A pending autosuspend can then run wsa883x_runtime_suspend() after the devm-managed regmap is freed, and dereference NULL, as seen on wsa884x. Use devm_pm_runtime_enable() so runtime PM is disabled before the regmap is freed. Fixes: 43b8c7dc85a1 ("ASoC: codecs: add wsa883x amplifier support") Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20261023171316.819857-6-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/wsa883x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index ccd4404c1644..b09ee3db7ed5 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -1669,7 +1669,9 @@ static int wsa883x_probe(struct sdw_slave *pdev, pm_runtime_use_autosuspend(dev); pm_runtime_mark_last_busy(dev); pm_runtime_set_active(dev); - pm_runtime_enable(dev); + ret = devm_pm_runtime_enable(dev); + if (ret) + goto err; ret = devm_snd_soc_register_component(dev, &wsa883x_component_drv, From a6093f98cbfc4a717ef3d1048b0e38fb2035be98 Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Fri, 23 Oct 2026 18:13:15 +0100 Subject: [PATCH 6/7] ASoC: codecs: wsa884x: Fix VI sense port channel count The VI sense port carries both the voltage and the current sense data of the speaker, but it is described with max_ch = 1 and, since commit 060fac202eb8 ("ASoC: codecs: wsa884x: Correct VI sense channel mask"), a channel mask of 0x1, so only half of the V/I pair is transferred. Describe the port as two channels and set the channel mask back to 0x3. Fixes: 060fac202eb8 ("ASoC: codecs: wsa884x: Correct VI sense channel mask") Cc: Krzysztof Kozlowski Signed-off-by: Ravi Hothi Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20261023171316.819857-7-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/wsa884x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c index 3c008224d32e..acf32af5aae3 100644 --- a/sound/soc/codecs/wsa884x.c +++ b/sound/soc/codecs/wsa884x.c @@ -859,7 +859,7 @@ static struct sdw_dpn_prop wsa884x_sink_dpn_prop[WSA884X_MAX_SWR_PORTS] = { .num = WSA884X_PORT_VISENSE + 1, .type = SDW_DPN_SIMPLE, .min_ch = 1, - .max_ch = 1, + .max_ch = 2, .simple_ch_prep_sm = true, .read_only_wordlength = true, }, @@ -892,7 +892,7 @@ static const struct sdw_port_config wsa884x_pconfig[WSA884X_MAX_SWR_PORTS] = { }, [WSA884X_PORT_VISENSE] = { .num = WSA884X_PORT_VISENSE + 1, - .ch_mask = 0x1, + .ch_mask = 0x3, }, [WSA884X_PORT_CPS] = { .num = WSA884X_PORT_CPS + 1, From 9728b328d7adf228d5f691d0ec43bb7a6d07e44b Mon Sep 17 00:00:00 2001 From: Ravi Hothi Date: Fri, 23 Oct 2026 18:13:16 +0100 Subject: [PATCH 7/7] ASoC: codecs: wsa883x: Fix VI sense port channel count The VI sense port carries both the voltage and the current sense data of the speaker, but it is described with max_ch = 1 and, since commit ed3b274abc40 ("ASoC: codecs: wsa883x: Correct VI sense channel mask"), a channel mask of 0x1, so only half of the V/I pair is transferred. Describe the port as two channels and set the channel mask back to 0x3. Fixes: ed3b274abc40 ("ASoC: codecs: wsa883x: Correct VI sense channel mask") Cc: Krzysztof Kozlowski Signed-off-by: Ravi Hothi Signed-off-by: Srinivas Kandagatla Link: https://patch.msgid.link/20261023171316.819857-8-srinivas.kandagatla@oss.qualcomm.com Signed-off-by: Mark Brown --- sound/soc/codecs/wsa883x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index b09ee3db7ed5..17d8babc6123 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -552,7 +552,7 @@ static struct sdw_dpn_prop wsa_sink_dpn_prop[WSA883X_MAX_SWR_PORTS] = { .num = WSA883X_PORT_VISENSE + 1, .type = SDW_DPN_SIMPLE, .min_ch = 1, - .max_ch = 1, + .max_ch = 2, .simple_ch_prep_sm = true, .read_only_wordlength = true, } @@ -573,7 +573,7 @@ static const struct sdw_port_config wsa883x_pconfig[WSA883X_MAX_SWR_PORTS] = { }, [WSA883X_PORT_VISENSE] = { .num = WSA883X_PORT_VISENSE + 1, - .ch_mask = 0x1, + .ch_mask = 0x3, }, };