summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2026-10-15 09:18:09 +0200
committerTakashi Iwai <tiwai@suse.de>2026-10-15 12:26:09 +0200
commit91d0048a97e0fdc0a071caa0ba59e659bc6f84df (patch)
tree3e4b674418e20a8a10b23c85dff493e5e48070b3 /include
parent85e8c5f933ee3dbc9d061e121237797e9fa05315 (diff)
ALSA: pcm: Add refcount for races between drain and unlink
We added a workaround for the case where a linked substream gets unlinked during the drain operation by another substream of the same linked group in the commit 9b1dbd69ba6f ("ALSA: pcm: fix use-after-free on linked stream runtime in snd_pcm_drain()"). There, we just cached the parameters of the draining substream for avoiding UAF. Then, we check the draining substream (to_check) again in the loop and remove it from the queue only when it's still present. It means, however, that the wait queue entry won't be removed if the substream went out of the link beforehand, hence a stale wq entry remains. Later on, this can be woken up, and this may hit a UAF, too. The problem surfaced more due to the recent change to call snd_pcm_unlink() earlier. For properly handling both cases above, in this patch, we introduce a refcount to the snd_pcm_runtime that indicates the substream is being accessed / used, then at snd_pcm_release_substream(), it's synced before the actual resource release via snd_refcount_sync(). This guarantees that the accessors are finished, and safe to release memories. Along with the introduction of a refcount, the comments and the code changes by the former fix were partially reverted as they don't fit with the updated code flow any longer. Last but not least, the setup of wait queue entry and prepare_to_wait() call are moved before the group unref. With this change, we can avoid the race between the enqueue and the wakeup, too. Fixes: 9b1dbd69ba6f ("ALSA: pcm: fix use-after-free on linked stream runtime in snd_pcm_drain()") Link: https://patch.msgid.link/20261015071838.31082-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'include')
-rw-r--r--include/sound/pcm.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 02d8689354c4..1cf511f8d880 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -8,6 +8,7 @@
* Abramo Bagnara <abramo@alsa-project.org>
*/
+#include <sound/core.h>
#include <sound/asound.h>
#include <sound/memalloc.h>
#include <sound/minors.h>
@@ -414,6 +415,7 @@ struct snd_pcm_runtime {
snd_pcm_uframes_t twake; /* do transfer (!poll) wakeup if non-zero */
wait_queue_head_t sleep; /* poll sleep */
wait_queue_head_t tsleep; /* transfer sleep */
+ struct snd_refcount refcnt; /* refcount for draining, etc */
struct snd_fasync *fasync;
bool stop_operating; /* sync_stop will be called */
struct mutex buffer_mutex; /* protect for buffer changes */