[PATCH] ALSA: control: fix refcount leak in snd_ctl_ioctl()

From: WenTao Liang

Date: Thu Jun 11 2026 - 22:35:29 EST


In snd_ctl_ioctl(), the TLV ioctl handlers (SNDRV_CTL_IOCTL_TLV_READ,
_WRITE, _COMMAND) call snd_power_ref_and_wait() to obtain a power
reference. That function always increments the card's power_ref count
even on failure, so any error return from these handlers must call
snd_power_unref(card) to balance the count.

The current code handles the 'err < 0' case by just returning err,
leaking a power reference each time an error occurs (e.g., when the
device is shutting down). Over time this can prevent the card from
being released properly.

Fix this by adding the missing snd_power_unref(card) before returning
on error in all three TLV ioctl cases.

Cc: stable@xxxxxxxxxxxxxxx
Fixes: fcc62b19104a ("ALSA: control: Take power_ref lock primarily")
Signed-off-by: WenTao Liang <vulab@xxxxxxxxxxx>
---
sound/core/control.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sound/core/control.c b/sound/core/control.c
index 7b714b5f8d54..e358e7463794 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -2028,8 +2028,10 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
return err;
case SNDRV_CTL_IOCTL_TLV_WRITE:
err = snd_power_ref_and_wait(card);
- if (err < 0)
+ if (err < 0) {
+ snd_power_unref(card);
return err;
+ }
scoped_guard(rwsem_write, &card->controls_rwsem)
err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE);
snd_power_unref(card);
--
2.50.1 (Apple Git-155)