summaryrefslogtreecommitdiff
path: root/tools/lib/python
diff options
context:
space:
mode:
authorCen Zhang <zzzccc427@gmail.com>2026-10-19 18:29:33 +0800
committerTakashi Iwai <tiwai@suse.de>2026-10-19 16:39:50 +0200
commitbb4834d5242c4829c0d8467ee68eb25a9bafc38d (patch)
tree12569337d48e8d46f4b53e7653cb35d9102734bc /tools/lib/python
parent8b479b265301e97bfbec0ef25de1c1f7eb4d2f74 (diff)
ALSA: pcm: Protect channel-map reads against runtime detach
Channel-map controls remain accessible between PCM opens. In-tree HDA code publishes the generic controls through add_std_chmaps(), so a SNDRV_CTL_IOCTL_ELEM_READ can overlap the final close of the same PCM substream. pcm_chmap_ctl_get() checks substream->runtime and later reads its channel count. Final close clears and frees that runtime under pcm->open_mutex, while the control callback holds only controls_rwsem: Control GET Final PCM close ----------- --------------- snd_ctl_elem_read() down_read(controls_rwsem) pcm_chmap_ctl_get() check substream->runtime lock(pcm->open_mutex) snd_pcm_release_substream() snd_pcm_detach_substream() substream->runtime = NULL kfree(runtime) unlock(pcm->open_mutex) substream->runtime->channels NULL or freed-pointer access up_read(controls_rwsem) Reloading the cleared field can fault through NULL, while retaining the old pointer can access freed storage. controls_rwsem keeps the control alive, but does not serialize the matching PCM close. Copy the channel count under open_mutex and use that scalar for the map lookup. Use trylock with -EBUSY because snd_pcm_dev_disconnect() takes open_mutex before removing controls under controls_rwsem; blocking in the reverse order from GET could deadlock. Fixes: 2d3391ec0ecc ("ALSA: PCM: channel mapping API implementation") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-0b5d6bc7124d0b921f2c-v4-b9738bdeab8823999181@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'tools/lib/python')
0 files changed, 0 insertions, 0 deletions