]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: hda: cs35l41: validate and free ACPI mute object
authorGuangshuo Li <lgs201920130244@gmail.com>
Wed, 8 Jul 2026 11:36:25 +0000 (19:36 +0800)
committerTakashi Iwai <tiwai@suse.de>
Wed, 15 Jul 2026 14:40:08 +0000 (16:40 +0200)
cs35l41_get_acpi_mute_state() evaluates a _DSM method to get the ACPI
mute state and reads the first byte from the returned object.

However, the returned ACPI object is owned by the caller and is never
freed after use, so each successful query leaks the _DSM result object.

The code also assumes that the returned object is a buffer with at least
one byte. A malformed firmware response can return a different object
type or an empty buffer, and the direct ret->buffer.pointer dereference
can then access an invalid pointer.

Use the typed _DSM helper, validate that the returned buffer contains at
least one byte, and free the ACPI object after reading it.

Fixes: 447106e92a0c ("ALSA: hda: cs35l41: Support mute notifications for CS35L41 HDA")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Link: https://patch.msgid.link/20260708113625.752913-1-lgs201920130244@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/hda/codecs/side-codecs/cs35l41_hda.c

index 64a5bd895fd1e6cecc379e0dc18a8f276b3c9c35..237059ef22f5c77c0e39133e59fc18ff9b06bd65 100644 (file)
@@ -1434,10 +1434,19 @@ static int cs35l41_get_acpi_mute_state(struct cs35l41_hda *cs35l41, acpi_handle
        guid_parse(CS35L41_UUID, &guid);
 
        if (cs35l41_dsm_supported(handle, CS35L41_DSM_GET_MUTE)) {
-               ret = acpi_evaluate_dsm(handle, &guid, 0, CS35L41_DSM_GET_MUTE, NULL);
+               ret = acpi_evaluate_dsm_typed(handle, &guid, 0,
+                             CS35L41_DSM_GET_MUTE, NULL,
+                             ACPI_TYPE_BUFFER);
+
                if (!ret)
                        return -EINVAL;
+               if (!ret->buffer.length || !ret->buffer.pointer) {
+                       ACPI_FREE(ret);
+                       return -EINVAL;
+               }
+
                mute = *ret->buffer.pointer;
+               ACPI_FREE(ret);
                dev_dbg(cs35l41->dev, "CS35L41_DSM_GET_MUTE: %d\n", mute);
        }