ALSA: core: Fix leaks at snd_card_init() error paths

When the snd_card object is initialized internally in snd_card_init(),
the error path of card->value_buf allocation returns straightly as an
error without invoking the destructor, which would leak resources.

Also, the other error paths in snd_card_init() release the card object
only via put_device(), and this misses the cleanups that are done in
snd_card_disconnect(); namely, the reserved slot bit in snd_cards_lock
is never cleared, so the card index remains occupied, and the debugfs
directory created for the card is left over.

Fix them by calling snd_card_free() at the error path, which performs
both the disconnection and the release properly.  As snd_card_free()
calls snd_device_free_all() internally, the explicit call is dropped,
and the error labels are unified.

Fixes: 84446536f6 ("ALSA: control: Verify put() result when in debug mode")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20261007172533.14667-7-tiwai@suse.de
This commit is contained in:
Takashi Iwai 2026-10-07 19:25:24 +02:00
parent f7faf5d9b5
commit 344e74ac50

View File

@ -334,7 +334,7 @@ static int snd_card_init(struct snd_card *card, struct device *parent,
err = snd_info_card_create(card);
if (err < 0) {
dev_err(parent, "unable to create card info\n");
goto __error_ctl;
goto __error;
}
#ifdef CONFIG_SND_DEBUG
@ -343,16 +343,16 @@ static int snd_card_init(struct snd_card *card, struct device *parent,
#endif
#ifdef CONFIG_SND_CTL_DEBUG
card->value_buf = kmalloc_obj(*card->value_buf);
if (!card->value_buf)
return -ENOMEM;
if (!card->value_buf) {
err = -ENOMEM;
goto __error;
}
#endif
return 0;
__error_ctl:
snd_device_free_all(card);
__error:
put_device(&card->card_dev);
return err;
snd_card_free(card);
return err;
}
/**