FAILED: patch "[PATCH] ALSA: core: Serialize deferred fasync state checks" failed to apply to 6.1-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x 5337213381df578058e2e41da93cbd0e4639935f
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026051252-doozy-thyself-9752@gregkh' --subject-prefix 'PATCH 6.1.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 5337213381df578058e2e41da93cbd0e4639935f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A1ssio=20Gabriel?= <[email protected]>
Date: Wed, 6 May 2026 00:34:47 -0300
Subject: [PATCH] ALSA: core: Serialize deferred fasync state checks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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.
sound/core/misc.c +6 -2
@@ -148,9 +148,11 @@ EXPORT_SYMBOL_GPL(snd_fasync_helper);void snd_kill_fasync (struct snd_fasync *fasync,int signal,int poll) { -if (!fasync || !fasync->on) +if (!fasync)return ;guard (spinlock_irqsave)(&snd_fasync_lock); +if (!fasync->on) +return ; fasync->signal = signal; fasync->poll = poll;list_move (&fasync->list, &snd_fasync_list);
@@ -163,8 +165,10 @@ void snd_fasync_free(struct snd_fasync *fasync)if (!fasync)return ; - scoped_guard(spinlock_irq, &snd_fasync_lock) + scoped_guard(spinlock_irq, &snd_fasync_lock) { + fasync->on =0 ;list_del_init (&fasync->list); + }flush_work (&snd_fasync_work);kfree (fasync);
Sasha Levin
maintainerPATCH 1/3 ALSA: misc: Use guard() for spin locks
From: Takashi Iwai <[email protected]>
[ Upstream commit b8e1684163ae52db90f428965bd9aaff7205c02e ]
Clean up the code using guard() for spin locks.
Merely code refactoring, and no behavior change.
Stable-dep-of: 5337213381df ("ALSA: core: Serialize deferred fasync state checks")
--- sound/core/misc.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-)
sound/core/misc.c +10 -15
@@ -198,35 +198,30 @@ int snd_fasync_helper(int fd, struct file *file, int on,INIT_LIST_HEAD (&fasync->list); } -spin_lock_irq (&snd_fasync_lock); -if (*fasyncp) { -kfree (fasync); - fasync = *fasyncp; - }else { -if (!fasync) { -spin_unlock_irq (&snd_fasync_lock); -return 0 ; + scoped_guard(spinlock_irq, &snd_fasync_lock) { +if (*fasyncp) { +kfree (fasync); + fasync = *fasyncp; + }else { +if (!fasync) +return 0 ; + *fasyncp = fasync; } - *fasyncp = fasync; + fasync->on = on; } - fasync->on = on; -spin_unlock_irq (&snd_fasync_lock);return fasync_helper (fd, file, on, &fasync->fasync); }EXPORT_SYMBOL_GPL (snd_fasync_helper);void snd_kill_fasync (struct snd_fasync *fasync,int signal,int poll) { -unsigned long flags; -if (!fasync || !fasync->on)return ; -spin_lock_irqsave (&snd_fasync_lock, flags); +guard (spinlock_irqsave)(&snd_fasync_lock); fasync->signal = signal; fasync->poll = poll;list_move (&fasync->list, &snd_fasync_list);schedule_work (&snd_fasync_work); -spin_unlock_irqrestore (&snd_fasync_lock, flags); }EXPORT_SYMBOL_GPL (snd_kill_fasync);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/3 ALSA: core: Fix potential data race at fasync handling
From: Takashi Iwai <[email protected]>
[ Upstream commit 8146cd333d235ed32d48bb803fdf743472d7c783 ]
In snd_fasync_work_fn(), which is the offload work for traversing and processing the pending fasync list, the call of kill_fasync() is done outside the snd_fasync_lock for avoiding deadlocks. The problem is that its the references of fasync->on, fasync->signal and fasync->poll are done there also outside the lock. Since these may be modified by snd_kill_fasync() call concurrently from other process, inconsistent values might be passed to kill_fasync(). Although there shouldn't be critical UAF, it's still better to be addressed.
This patch moves the kill_fasync() argument evaluations inside the snd_fasync_lock for avoiding the data races above. The handling in fasync->on flag is optimized in the loop to skip directly.
Also, for more clarity, snd_fasync_free() takes the lock and unlink the pending entry more directly instead of clearing fasync->on flag.
Stable-dep-of: 5337213381df ("ALSA: core: Serialize deferred fasync state checks")
--- sound/core/misc.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
sound/core/misc.c +10 -3
@@ -171,14 +171,18 @@ static LIST_HEAD(snd_fasync_list);static void snd_fasync_work_fn (struct work_struct *work) {struct snd_fasync *fasync; +int signal, poll;spin_lock_irq (&snd_fasync_lock);while (!list_empty (&snd_fasync_list)) { fasync = list_first_entry(&snd_fasync_list, struct snd_fasync, list);list_del_init (&fasync->list); +if (!fasync->on) +continue ; + signal = fasync->signal; + poll = fasync->poll;spin_unlock_irq (&snd_fasync_lock); -if (fasync->on) -kill_fasync (&fasync->fasync, fasync->signal, fasync->poll); +kill_fasync (&fasync->fasync, signal, poll);spin_lock_irq (&snd_fasync_lock); }spin_unlock_irq (&snd_fasync_lock);
@@ -229,7 +233,10 @@ void snd_fasync_free(struct snd_fasync *fasync) {if (!fasync)return ; - fasync->on =0 ; + + scoped_guard(spinlock_irq, &snd_fasync_lock) +list_del_init (&fasync->list); +flush_work (&snd_fasync_work);kfree (fasync); }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/3 ALSA: core: Serialize deferred fasync state checks
In reply to Sasha LevinFrom: Cássio Gabriel <[email protected]>
[ Upstream commit 5337213381df578058e2e41da93cbd0e4639935f ]
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.
--- sound/core/misc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
sound/core/misc.c +6 -2
@@ -219,9 +219,11 @@ EXPORT_SYMBOL_GPL(snd_fasync_helper);void snd_kill_fasync (struct snd_fasync *fasync,int signal,int poll) { -if (!fasync || !fasync->on) +if (!fasync)return ;guard (spinlock_irqsave)(&snd_fasync_lock); +if (!fasync->on) +return ; fasync->signal = signal; fasync->poll = poll;list_move (&fasync->list, &snd_fasync_list);
@@ -234,8 +236,10 @@ void snd_fasync_free(struct snd_fasync *fasync)if (!fasync)return ; - scoped_guard(spinlock_irq, &snd_fasync_lock) + scoped_guard(spinlock_irq, &snd_fasync_lock) { + fasync->on =0 ;list_del_init (&fasync->list); + }flush_work (&snd_fasync_work);kfree (fasync);
Signature · 1 line
2.53.0