[PATCH 1/2] ALSA: hda: cs35l56: Free ACPI _SUB string on errors
From: Cássio Gabriel
Date: Wed May 20 2026 - 08:54:17 EST
cs35l56_hda_read_acpi() gets an allocated ACPI _SUB string from
acpi_get_subsystem_id(). On success, that string is either transferred
to cs35l56->system_name or freed after constructing a speaker-ID-specific
firmware name.
Several error paths after the _SUB lookup return without releasing the
allocated string. This includes speaker ID lookup errors other than
-ENOENT, and errors after _SUB is read but before ownership is
transferred to cs35l56->system_name.
Free the temporary _SUB string on those error paths. If ownership has
already been transferred to cs35l56->system_name, free that member and
clear it before returning the error.
Fixes: 6f03b446cbae ("ALSA: hda: cs35l56: Add support for speaker id")
Fixes: 40b1c2f9b299 ("ALSA: hda/cs35l56: Workaround bad dev-index on Lenovo Yoga Book 9i GenX")
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@xxxxxxxxx>
---
sound/hda/codecs/side-codecs/cs35l56_hda.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda.c b/sound/hda/codecs/side-codecs/cs35l56_hda.c
index cdbc576569ef..7b5fc63eeaa8 100644
--- a/sound/hda/codecs/side-codecs/cs35l56_hda.c
+++ b/sound/hda/codecs/side-codecs/cs35l56_hda.c
@@ -1050,7 +1050,7 @@ static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)
sub = acpi_get_subsystem_id(ACPI_HANDLE(cs35l56->base.dev));
ret = cs35l56_hda_apply_platform_fixups(cs35l56, sub, &id);
if (ret)
- return ret;
+ goto err_free_sub;
if (cs35l56->index == -1) {
property = "cirrus,dev-index";
@@ -1102,7 +1102,7 @@ static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)
if (!cs35l56->system_name)
return -ENOMEM;
} else {
- return ret;
+ goto err_free_sub;
}
}
@@ -1117,8 +1117,11 @@ static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)
* If RESET is shared the first amp to probe will grab the reset
* line and reset all the amps
*/
- if (ret != -EBUSY)
- return dev_err_probe(cs35l56->base.dev, ret, "Failed to get reset GPIO\n");
+ if (ret != -EBUSY) {
+ ret = dev_err_probe(cs35l56->base.dev, ret,
+ "Failed to get reset GPIO\n");
+ goto err_free_system_name;
+ }
dev_info(cs35l56->base.dev, "Reset GPIO busy, assume shared reset\n");
cs35l56->base.reset_gpio = NULL;
@@ -1126,10 +1129,20 @@ static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)
return 0;
+err_free_system_name:
+ kfree(cs35l56->system_name);
+ cs35l56->system_name = NULL;
+
+ return ret;
+
err:
if (ret != -ENODEV)
dev_err(cs35l56->base.dev, "Failed property %s: %d\n", property, ret);
+err_free_sub:
+ if (!IS_ERR(sub))
+ kfree(sub);
+
return ret;
}
--
2.54.0