* [PATCH] ASoC: soc-core: start rtd->num_components at zero
@ 2026-11-12 2:52 Dennis Gilmore
2026-11-12 11:37 ` Mark Brown
0 siblings, 1 reply; 4+ messages in thread
From: Dennis Gilmore @ 2026-11-12 2:52 UTC (permalink / raw)
To: broonie, lgirdwood
Cc: perex, tiwai, kees, gustavoars, linux-sound, linux-hardening,
linux-kernel, michael.hennerich, nuno.sa, dlechner, linux-spi,
miriam.rachel.korenblit, linux-wireless, Dennis Gilmore
Since the conversion to devm_kzalloc_flex(), the allocator sets the
__counted_by() counter num_components to the allocated length
(num_cpus + num_codecs + num_platforms). This only happens when the
compiler supports __builtin_counted_by_ref() (GCC 16 here). With
older compilers the counter stays zero, as before.
snd_soc_rtd_add_component() treats num_components as the number of
components added so far: it increments the counter and stores the
new component at num_components - 1. Starting from the preset
length, every component is written past the end of the allocation.
On a link with one CPU, one codec and one platform, entries 3 to 5
of a 3-entry array are written, and components[0] stays NULL.
for_each_rtd_components() stops at that NULL entry, so
soc_probe_link_components() probes no component, and
component->card stays NULL for every component on the card. The
first DAI .probe callback that uses its component's card then
dereferences NULL. On an HP OmniBook X 14 (MediaTek MT8901
SoundWire with CS42L43 and CS35L56 codecs) binding the card
crashes in cs42l43_dai_probe():
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000038
Internal error: Oops: 0000000096000004 [#1] SMP
pc : snd_soc_card_get_kcontrol+0x18/0x40 [snd_soc_core]
lr : snd_soc_component_get_kcontrol+0x6c/0xc0 [snd_soc_core]
Call trace:
snd_soc_card_get_kcontrol+0x18/0x40 [snd_soc_core] (P)
snd_soc_component_get_kcontrol+0x6c/0xc0 [snd_soc_core]
cs42l43_dai_probe+0xb0/0x148 [snd_soc_cs42l43]
snd_soc_pcm_dai_probe+0x70/0xf8 [snd_soc_core]
snd_soc_bind_card+0x4d4/0x8c0 [snd_soc_core]
call_soc_bind_card+0x70/0xf0 [snd_soc_core]
snd_soc_register_card+0xd8/0x110 [snd_soc_core]
devm_snd_soc_register_card+0x20/0x38 [snd_soc_core]
mt8901_card_probe+0x258/0x5c8 [mt8901_acp_sdw_legacy_mach]
platform_probe+0x88/0xc0
Reset the counter after allocation, so components are added from
index 0 again as they were before the conversion.
The bug was found, and this fix written, with the help of an AI
coding assistant (Claude). Tested on the HP OmniBook X 14: the card
binds and playback and capture work.
Fixes: 4dd10fbbeb9c ("treewide: Convert devm_kmalloc() family to the devm_kmalloc_obj() family")
Signed-off-by: Dennis Gilmore <dennis@ausil.us>
---
An alternative fix would be to keep num_components as the array size
and have snd_soc_rtd_add_component() fill the first NULL slot. The
counter would still need to be set explicitly, because the preset does
not happen on compilers without __builtin_counted_by_ref(). Resetting it
keeps the original design and the tighter __counted_by() bounds.
Kees, the same pattern (a *_flex() allocation followed by code that uses
the counter as a fill index starting from zero) looks to be present in
two places converted by 69050f8d6d07 ("treewide: Replace kmalloc with
kmalloc_obj for non-scalar types"). I have only read the code for these.
I have no hardware for either and have not reproduced them, so please
treat them as possible issues rather than confirmed bugs:
- drivers/spi/spi-axi-spi-engine.c: spi_engine_optimize_message()
allocates p with kzalloc_flex(*p, instructions, p_dry.length + 1),
which presets p->length, and spi_engine_compile_message() then
appends with p->length++ through spi_engine_program_add_cmd().
- drivers/net/wireless/intel/iwlwifi/mld/d3.c:
iwl_mld_process_netdetect_res() allocates netdetect_info with
kzalloc_flex(..., matches, n_matches), presetting n_matches, and
iwl_mld_set_netdetect_info() stores at matches[n_matches] and then
increments it. The per-match kzalloc_flex(..., channels, n_channels)
has the same issue with match->n_channels.
If they are real, the fix would be the same as here. I'm happy to send
patches. It may also be worth a Coccinelle check for this pattern.
sound/soc/soc-core.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 68b54e509b65..e4d911577c5f 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -388,6 +388,13 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
return NULL;
}
+ /*
+ * devm_kzalloc_flex() presets the __counted_by() counter to the
+ * allocated size, but snd_soc_rtd_add_component() uses
+ * num_components as the number of components added so far.
+ */
+ rtd->num_components = 0;
+
rtd->dev = dev;
INIT_LIST_HEAD(&rtd->list);
for_each_pcm_streams(stream) {
--
2.56.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] ASoC: soc-core: start rtd->num_components at zero
2026-11-12 2:52 [PATCH] ASoC: soc-core: start rtd->num_components at zero Dennis Gilmore
@ 2026-11-12 11:37 ` Mark Brown
2026-11-12 13:32 ` Hans de Goede
2026-11-12 13:34 ` Hans de Goede
0 siblings, 2 replies; 4+ messages in thread
From: Mark Brown @ 2026-11-12 11:37 UTC (permalink / raw)
To: Dennis Gilmore
Cc: broonie, lgirdwood, perex, tiwai, kees, gustavoars, linux-sound,
linux-hardening, linux-kernel, michael.hennerich, nuno.sa,
dlechner, linux-spi, miriam.rachel.korenblit, linux-wireless
> Since the conversion to devm_kzalloc_flex(), the allocator sets the
> __counted_by() counter num_components to the allocated length
> (num_cpus + num_codecs + num_platforms). This only happens when the
> compiler supports __builtin_counted_by_ref() (GCC 16 here). With
> older compilers the counter stays zero, as before.
This doesn't apply against current code, I think this is an issue that
was already fixed. Please check and resend if it's still needed.
--
Mark Brown <broonie@kernel.org>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] ASoC: soc-core: start rtd->num_components at zero
2026-11-12 11:37 ` Mark Brown
@ 2026-11-12 13:32 ` Hans de Goede
2026-11-12 13:34 ` Hans de Goede
1 sibling, 0 replies; 4+ messages in thread
From: Hans de Goede @ 2026-11-12 13:32 UTC (permalink / raw)
To: Mark Brown, Dennis Gilmore, kees
Cc: lgirdwood, perex, tiwai, gustavoars, linux-sound,
linux-hardening, linux-kernel, michael.hennerich, nuno.sa,
dlechner, linux-spi, miriam.rachel.korenblit, linux-wireless
Hi Mark,
I was about to send a regression bug report for 7.4-rc2 but I first
checked the list to see if a fix was already available and I'm happy
to report that this fixes things for me:
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Also the patch looks good to me:
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
On 12-Nov-26 12:37, Mark Brown wrote:
>> Since the conversion to devm_kzalloc_flex(), the allocator sets the
>> __counted_by() counter num_components to the allocated length
>> (num_cpus + num_codecs + num_platforms). This only happens when the
>> compiler supports __builtin_counted_by_ref() (GCC 16 here). With
>> older compilers the counter stays zero, as before.
>
> This doesn't apply against current code, I think this is an issue that
> was already fixed. Please check and resend if it's still needed.
This applies cleanly on 7.4-rc2 and fixes a regression breaking
audio on a lot of different devices there.
If some form of this is already in ASoC-next, then that needs to be
send to Linux as a fix ASAP.
@Kees, have you seen Dennis' remark about the
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] ASoC: soc-core: start rtd->num_components at zero
2026-11-12 11:37 ` Mark Brown
2026-11-12 13:32 ` Hans de Goede
@ 2026-11-12 13:34 ` Hans de Goede
1 sibling, 0 replies; 4+ messages in thread
From: Hans de Goede @ 2026-11-12 13:34 UTC (permalink / raw)
To: Mark Brown, Dennis Gilmore, kees
Cc: lgirdwood, perex, tiwai, gustavoars, linux-sound,
linux-hardening, linux-kernel, michael.hennerich, nuno.sa,
dlechner, linux-spi, miriam.rachel.korenblit, linux-wireless
Hi Mark,
I was about to send a regression bug report for 7.4-rc2 but I first
checked the list to see if a fix was already available and I'm happy
to report that this fixes things for me:
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
On 12-Nov-26 12:37, Mark Brown wrote:
>> Since the conversion to devm_kzalloc_flex(), the allocator sets the
>> __counted_by() counter num_components to the allocated length
>> (num_cpus + num_codecs + num_platforms). This only happens when the
>> compiler supports __builtin_counted_by_ref() (GCC 16 here). With
>> older compilers the counter stays zero, as before.
>
> This doesn't apply against current code, I think this is an issue that
> was already fixed. Please check and resend if it's still needed.
This applies cleanly on 7.4-rc2 and fixes a regression breaking
audio on a lot of different devices there.
If some form of this is already in ASoC-next, then that needs to be
send to Linux as a fix ASAP.
Regards,
Hans
p.s.
@Kees, have you seen Dennis' remark about the same problem with
devm_kzalloc_flex() changing the semantics with the num-components
counter now no longer being initialized to zero in at least 2 other
places? :
"""
Kees, the same pattern (a *_flex() allocation followed by code that uses
the counter as a fill index starting from zero) looks to be present in
two places converted by 69050f8d6d07 ("treewide: Replace kmalloc with
kmalloc_obj for non-scalar types"). I have only read the code for these.
I have no hardware for either and have not reproduced them, so please
treat them as possible issues rather than confirmed bugs:
- drivers/spi/spi-axi-spi-engine.c: spi_engine_optimize_message()
allocates p with kzalloc_flex(*p, instructions, p_dry.length + 1),
which presets p->length, and spi_engine_compile_message() then
appends with p->length++ through spi_engine_program_add_cmd().
- drivers/net/wireless/intel/iwlwifi/mld/d3.c:
iwl_mld_process_netdetect_res() allocates netdetect_info with
kzalloc_flex(..., matches, n_matches), presetting n_matches, and
iwl_mld_set_netdetect_info() stores at matches[n_matches] and then
increments it. The per-match kzalloc_flex(..., channels, n_channels)
has the same issue with match->n_channels.
"""
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-12 13:34 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-12 2:52 [PATCH] ASoC: soc-core: start rtd->num_components at zero Dennis Gilmore
2026-11-12 11:37 ` Mark Brown
2026-11-12 13:32 ` Hans de Goede
2026-11-12 13:34 ` Hans de Goede
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®