mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] ALSA: core: some power-state hardening
@ 2026-09-29 12:53 Takashi Iwai
  2026-09-29 12:53 ` [PATCH 1/2] ALSA: core: Check shutdown flag at D0 power-state, too Takashi Iwai
  2026-09-29 12:53 ` [PATCH 2/2] ALSA: control: Fix UAF in snd_ctl_elem_add() on card disconnect Takashi Iwai
  0 siblings, 2 replies; 3+ messages in thread
From: Takashi Iwai @ 2026-09-29 12:53 UTC (permalink / raw)
  To: linux-sound; +Cc: linux-kernel, Farhad Alemi

Hi,

there was a report about a UAF with the inconsistent power-state
handling.  This is a couple of small patches to address such corner
cases.


Takashi

===

Takashi Iwai (2):
  ALSA: core: Check shutdown flag at D0 power-state, too
  ALSA: control: Fix UAF in snd_ctl_elem_add() on card disconnect

 sound/core/control.c |  2 ++
 sound/core/init.c    | 12 ++++++------
 2 files changed, 8 insertions(+), 6 deletions(-)

-- 
2.55.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] ALSA: core: Check shutdown flag at D0 power-state, too
  2026-09-29 12:53 [PATCH 0/2] ALSA: core: some power-state hardening Takashi Iwai
@ 2026-09-29 12:53 ` Takashi Iwai
  2026-09-29 12:53 ` [PATCH 2/2] ALSA: control: Fix UAF in snd_ctl_elem_add() on card disconnect Takashi Iwai
  1 sibling, 0 replies; 3+ messages in thread
From: Takashi Iwai @ 2026-09-29 12:53 UTC (permalink / raw)
  To: linux-sound; +Cc: linux-kernel, Farhad Alemi

The snd_power_ref_and_wait() skips the card->shutdown check when the
card is already in D0 state and immediately returns as successful, by
assuming the all-green in D0.  This assumption makes the code after
this sync point behaving as if all power is up and ready, even though
actually it might have been already at the disconnected state.

Add the missing check of shutdown flag there for the more consistent
behavior.

Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/init.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/sound/core/init.c b/sound/core/init.c
index 1bcb6a2e7550..a51b71812fd9 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -1174,12 +1174,12 @@ EXPORT_SYMBOL(snd_card_file_remove);
 int snd_power_ref_and_wait(struct snd_card *card)
 {
 	snd_power_ref(card);
-	if (snd_power_get_state(card) == SNDRV_CTL_POWER_D0)
-		return 0;
-	wait_event_cmd(card->power_sleep,
-		       card->shutdown ||
-		       snd_power_get_state(card) == SNDRV_CTL_POWER_D0,
-		       snd_power_unref(card), snd_power_ref(card));
+	if (snd_power_get_state(card) != SNDRV_CTL_POWER_D0) {
+		wait_event_cmd(card->power_sleep,
+			       card->shutdown ||
+			       snd_power_get_state(card) == SNDRV_CTL_POWER_D0,
+			       snd_power_unref(card), snd_power_ref(card));
+	}
 	if (card->shutdown) {
 		snd_power_unref(card);
 		return  -ENODEV;
-- 
2.55.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/2] ALSA: control: Fix UAF in snd_ctl_elem_add() on card disconnect
  2026-09-29 12:53 [PATCH 0/2] ALSA: core: some power-state hardening Takashi Iwai
  2026-09-29 12:53 ` [PATCH 1/2] ALSA: core: Check shutdown flag at D0 power-state, too Takashi Iwai
@ 2026-09-29 12:53 ` Takashi Iwai
  1 sibling, 0 replies; 3+ messages in thread
From: Takashi Iwai @ 2026-09-29 12:53 UTC (permalink / raw)
  To: linux-sound; +Cc: linux-kernel, Farhad Alemi

A use-after-free can be triggered via SNDRV_CTL_IOCTL_ELEM_ADD when a
USB audio card is disconnected while an ELEM_ADD ioctl is in flight.

The reproducer parks the ioctl thread inside copy_from_user() using
userfaultfd, then tears down the USB device.  Unlike every other
ALSA control _user handler (ELEM_INFO, ELEM_READ, ELEM_WRITE, TLV_*),
snd_ctl_elem_add_user() never calls snd_power_ref_and_wait(), so the
parked thread holds no power reference.  snd_card_disconnect() therefore
cannot observe it via snd_power_sync_ref() and proceeds unimpeded:

  1. card->shutdown is set to 1
  2. device_del(&card->card_dev) drops the kobject reference on the
     parent USB interface device (card->dev = &intf->dev)
  3. The USB core drops its own reference and calls device_release(),
     freeing the struct usb_interface, including the embedded struct
     device that card->dev points to

When the userfaultfd is resolved and the thread resumes,
snd_ctl_elem_add() acquires controls_rwsem without checking
card->shutdown and calls __snd_ctl_add_replace().  Because the
reproducer pre-registered the same control, the CTL_ADD_EXCLUSIVE
path calls dev_err(card->dev, ...) on the freed USB interface:

  KASAN: slab-use-after-free Read in __dev_printk

Add a card->shutdown guard immediately after acquiring controls_rwsem
in snd_ctl_elem_add().  At that point card->shutdown is guaranteed to
be stable: snd_card_disconnect() sets it before freeing the parent
device, and it never transitions back to 0.  A thread that acquired
the lock before disconnect sees shutdown=0 and holds the write lock
through the rest of the operation, preventing concurrent disconnect
from proceeding past its own controls_rwsem-less shutdown=1 store
(which happened earlier, outside the lock) from racing with dev_err().

Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/control.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/core/control.c b/sound/core/control.c
index 4199342d4ffe..535ceba294ac 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1802,6 +1802,8 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
 	alloc_size = compute_user_elem_size(private_size, count);
 
 	guard(rwsem_write)(&card->controls_rwsem);
+	if (card->shutdown)
+		return -ENODEV;
 	if (check_user_elem_overflow(card, alloc_size))
 		return -ENOMEM;
 
-- 
2.55.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-29 12:54 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-29 12:53 [PATCH 0/2] ALSA: core: some power-state hardening Takashi Iwai
2026-09-29 12:53 ` [PATCH 1/2] ALSA: core: Check shutdown flag at D0 power-state, too Takashi Iwai
2026-09-29 12:53 ` [PATCH 2/2] ALSA: control: Fix UAF in snd_ctl_elem_add() on card disconnect Takashi Iwai

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®