Linux Sound subsystem development
 help / color / mirror / Atom feed
* [PATCH] ALSA: jack: Protect the index scan against control removal
@ 2026-10-17  7:00 Cen Zhang
  2026-10-17  8:22 ` Takashi Iwai
  0 siblings, 1 reply; 2+ messages in thread
From: Cen Zhang @ 2026-10-17  7:00 UTC (permalink / raw)
  To: perex, tiwai; +Cc: linux-sound, linux-kernel, baijiaju1990, jjzuming, zzzccc427

A control found during a jack-name index scan must remain alive until
snd_ctl_find_id() finishes comparing its ID and count. However,
get_available_index() calls it without holding card->controls_rwsem.
With CONFIG_SND_CTL_FAST_LOOKUP enabled, the lookup loads a raw control
pointer from ctl_hash and dereferences it in elem_id_matches() without
any lock that excludes removal.

This can happen when a jack is created while a different jack owner on
the same card removes an existing control with the same name and index.
For example, probe and unbind of different HDA codecs can reach these
paths on a shared card if their generated jack names match.
The codec device locks do not serialize operations on different
codecs. The unbind path can free the control during the index scan:

  Codec A: probe                  Codec B: unbind
  --------------                  ---------------
  get_available_index()
    snd_ctl_find_id()
      kctl = xa_load(...)
                                  hda_codec_driver_remove()
                                    snd_hda_codec_cleanup_for_unbind()
                                      snd_hda_jack_tbl_clear()
                                        snd_device_free()
                                          __snd_device_free()
                                            snd_jack_dev_free()
                                              snd_ctl_remove()
                                                snd_ctl_remove_locked()
                                                  __snd_ctl_remove()
                                                    snd_ctl_free_one()
                                                      kfree(kctl)
      elem_id_matches(kctl, ...)
        read freed id/count -> UAF

Hold controls_rwsem for read across the index scan so removal cannot
free a control until the lookup has finished using it. Release the lock
when get_available_index() returns, before the caller adds the new
control under the write lock.

Fixes: 38ea4c3dc306 ("ALSA: control: Optimize locking for look-up")
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Assisted-by: LLM

---

diff --git a/sound/core/ctljack.c b/sound/core/ctljack.c
index 6b6ab34fbde89a6551eb634ce13c66922770d0e5..36700fda79f3c027e84bad416c4dcc3d5da1c6bd 100644
--- a/sound/core/ctljack.c
+++ b/sound/core/ctljack.c
@@ -38,6 +38,7 @@ static int get_available_index(struct snd_card *card, const char *name)
 	sid.iface = SNDRV_CTL_ELEM_IFACE_CARD;
 	strscpy(sid.name, name, sizeof(sid.name));
 
+	guard(rwsem_read)(&card->controls_rwsem);
 	while (snd_ctl_find_id(card, &sid)) {
 		sid.index++;
 		/* reset numid; otherwise snd_ctl_find_id() hits this again */

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

* Re: [PATCH] ALSA: jack: Protect the index scan against control removal
  2026-10-17  7:00 [PATCH] ALSA: jack: Protect the index scan against control removal Cen Zhang
@ 2026-10-17  8:22 ` Takashi Iwai
  0 siblings, 0 replies; 2+ messages in thread
From: Takashi Iwai @ 2026-10-17  8:22 UTC (permalink / raw)
  To: Cen Zhang; +Cc: perex, tiwai, linux-sound, linux-kernel, baijiaju1990, jjzuming

On Sat, 17 Oct 2026 09:00:58 +0200,
Cen Zhang wrote:
> 
> A control found during a jack-name index scan must remain alive until
> snd_ctl_find_id() finishes comparing its ID and count. However,
> get_available_index() calls it without holding card->controls_rwsem.
> With CONFIG_SND_CTL_FAST_LOOKUP enabled, the lookup loads a raw control
> pointer from ctl_hash and dereferences it in elem_id_matches() without
> any lock that excludes removal.
> 
> This can happen when a jack is created while a different jack owner on
> the same card removes an existing control with the same name and index.
> For example, probe and unbind of different HDA codecs can reach these
> paths on a shared card if their generated jack names match.
> The codec device locks do not serialize operations on different
> codecs. The unbind path can free the control during the index scan:
> 
>   Codec A: probe                  Codec B: unbind
>   --------------                  ---------------
>   get_available_index()
>     snd_ctl_find_id()
>       kctl = xa_load(...)
>                                   hda_codec_driver_remove()
>                                     snd_hda_codec_cleanup_for_unbind()
>                                       snd_hda_jack_tbl_clear()
>                                         snd_device_free()
>                                           __snd_device_free()
>                                             snd_jack_dev_free()
>                                               snd_ctl_remove()
>                                                 snd_ctl_remove_locked()
>                                                   __snd_ctl_remove()
>                                                     snd_ctl_free_one()
>                                                       kfree(kctl)
>       elem_id_matches(kctl, ...)
>         read freed id/count -> UAF
> 
> Hold controls_rwsem for read across the index scan so removal cannot
> free a control until the lookup has finished using it. Release the lock
> when get_available_index() returns, before the caller adds the new
> control under the write lock.
> 
> Fixes: 38ea4c3dc306 ("ALSA: control: Optimize locking for look-up")
> Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
> Assisted-by: LLM

Applied to for-next branch now.

There is no real race in the currently used code (it's called only at
the card probe time, hence no race against the card removal), but it's
a generic helper that may be used at any moment, so it's good to cover.


thanks,

Takashi

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

end of thread, other threads:[~2026-10-17  8:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-17  7:00 [PATCH] ALSA: jack: Protect the index scan against control removal Cen Zhang
2026-10-17  8:22 ` Takashi Iwai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox