Re: [PATCH] ALSA: jack: Protect the index scan against control removal
From: Takashi Iwai
Date: Sat Oct 17 2026 - 04:23:32 EST
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@xxxxxxxxx>
> 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