Skip to content

Commit 878c19d

Browse files
CassivsGabriellisgregkh
authored andcommitted
ALSA: core: Serialize deferred fasync state checks
commit 5337213 upstream. snd_fasync_helper() updates fasync->on under snd_fasync_lock, and snd_fasync_work_fn() now also evaluates fasync->on under the same lock. snd_kill_fasync() still tests the flag before taking the lock, leaving an unsynchronized read against FASYNC enable/disable updates. Move the enabled-state check into the locked section. Also clear fasync->on under snd_fasync_lock in snd_fasync_free() before unlinking the pending entry. Together with the locked sender-side check, this publishes teardown before flushing the deferred work and prevents a racing sender from requeueing the entry after free has started. Fixes: ef34a0a ("ALSA: core: Add async signal helpers") Fixes: 8146cd3 ("ALSA: core: Fix potential data race at fasync handling") Cc: stable@vger.kernel.org Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com> Link: https://patch.msgid.link/20260506-alsa-core-fasync-on-lock-v1-1-ea48c77d6ca4@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent d761428 commit 878c19d

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

sound/core/misc.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,11 @@ EXPORT_SYMBOL_GPL(snd_fasync_helper);
148148

149149
void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll)
150150
{
151-
if (!fasync || !fasync->on)
151+
if (!fasync)
152152
return;
153153
guard(spinlock_irqsave)(&snd_fasync_lock);
154+
if (!fasync->on)
155+
return;
154156
fasync->signal = signal;
155157
fasync->poll = poll;
156158
list_move(&fasync->list, &snd_fasync_list);
@@ -163,8 +165,10 @@ void snd_fasync_free(struct snd_fasync *fasync)
163165
if (!fasync)
164166
return;
165167

166-
scoped_guard(spinlock_irq, &snd_fasync_lock)
168+
scoped_guard(spinlock_irq, &snd_fasync_lock) {
169+
fasync->on = 0;
167170
list_del_init(&fasync->list);
171+
}
168172

169173
flush_work(&snd_fasync_work);
170174
kfree(fasync);

0 commit comments

Comments
 (0)