<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/sound/core, branch v6.18.48</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v6.18.48</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v6.18.48'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2026-08-09T18:25:14+00:00</updated>
<entry>
<title>ALSA: ump: fix double free of out_cvts on rawmidi error</title>
<updated>2026-08-09T18:25:14+00:00</updated>
<author>
<name>Baul Lee</name>
<email>baul.lee@xbow.com</email>
</author>
<published>2026-07-26T05:16:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=032746c2dd9a4ea0774b04ac8a29e2ea628f106e'/>
<id>urn:sha1:032746c2dd9a4ea0774b04ac8a29e2ea628f106e</id>
<content type='text'>
commit 70c977815af0d997feb2d0c5d284d55689bf7051 upstream.

snd_ump_attach_legacy_rawmidi() allocates the legacy conversion array
ump-&gt;out_cvts and, on the snd_rawmidi_new() error path, frees it with
kfree() but leaves ump-&gt;out_cvts pointing at the freed memory.  When the
endpoint is later torn down, snd_ump_endpoint_free() frees ump-&gt;out_cvts
a second time, resulting in a double free.

The host snd-usb-audio driver attaches the legacy rawmidi for any USB
MIDI 2.0 (UMP) device, so a device that makes snd_rawmidi_new() fail
reaches this path on enumeration.

Clear ump-&gt;out_cvts after freeing it on the error path so it is not
freed again during teardown.

Discovered by XBOW, triaged by Baul Lee &lt;baul.lee@xbow.com&gt;

Fixes: 33cd7630782d ("ALSA: ump: Export MIDI1 / UMP conversion helpers")
Reported-by: Federico Kirschbaum &lt;federico.kirschbaum@xbow.com&gt;
Reported-by: Baul Lee &lt;baul.lee@xbow.com&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Baul Lee &lt;baul.lee@xbow.com&gt;
Link: https://patch.msgid.link/20260726051633.41206-1-baul.lee@xbow.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ALSA: timer: Clear SNDRV_TIMER_IFLG_DEAD once the close completes</title>
<updated>2026-08-09T18:25:14+00:00</updated>
<author>
<name>Norbert Szetei</name>
<email>norbert@doyensec.com</email>
</author>
<published>2026-07-26T08:01:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=a26a2e52736f9e39843ca66a2e1ce6bf1adbcd1e'/>
<id>urn:sha1:a26a2e52736f9e39843ca66a2e1ce6bf1adbcd1e</id>
<content type='text'>
commit c2744d5f3aea474513fd2298daecb94a952ce441 upstream.

snd_timer_close_locked() marks an instance with SNDRV_TIMER_IFLG_DEAD
and returns early when the flag is already set, but the flag is never
cleared again.  A completed close ends in remove_slave_links(), which
leaves timeri-&gt;timer NULL, so a second close is already harmless through
the timer == NULL path; the early return can only be reached by an
instance that was opened again in between.  For such an instance the
close unlinks nothing, so snd_timer_instance_free() frees an object that
is still on timer-&gt;open_list_head, still on snd_timer_master_list if it
was opened with a slave key, still owns any adopted slaves, and still
holds its timer and module references.

snd_seq_timer_open() reopens an instance exactly like that: it retries
its fallback open on the same object after a failure that has already
run snd_timer_close_locked() internally.  An unprivileged user with
access to /dev/snd/timer and /dev/snd/seq can force that failure, since
snd_timer_check_master() returns -EBUSY when a pending slave matches the
new master's (slave_class, slave_id) key and the target timer has
reached max_instances, and SNDRV_TIMER_IOCTL_SELECT with dev_class =
SNDRV_TIMER_CLASS_SLAVE keeps the caller-supplied dev_sclass, so a
sequencer queue's key can be forged.  The freed instance is afterwards
dereferenced by any further snd_timer_open() on that timer, by
snd_timer_check_slave(), and by /proc/asound/timers, which faults on the
stale ti-&gt;owner pointer.

The flag only has to be visible while the close is in progress, which is
all its other users need.  Clear it in remove_slave_links(), under the
same timer-&gt;lock that sets it, once the instance is off every list.

Fixes: da3039e91d1f ("ALSA: timer: Forcibly close timer instances at closing")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Norbert Szetei &lt;norbert@doyensec.com&gt;
Link: https://patch.msgid.link/CA41AA48-75BF-45E9-A36D-3A5D2F124F60@doyensec.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ALSA: seq: Fix division by zero in initialize_timer()</title>
<updated>2026-08-09T18:25:13+00:00</updated>
<author>
<name>Norbert Szetei</name>
<email>norbert@doyensec.com</email>
</author>
<published>2026-07-25T06:33:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=5260e195c53e898a4a76527d4bb2178f31795e78'/>
<id>urn:sha1:5260e195c53e898a4a76527d4bb2178f31795e78</id>
<content type='text'>
commit 21e19688433452dfbbbe6b2bb670dea6eb92f0f6 upstream.

A userspace-driven ALSA timer (SND_UTIMER) lets an unprivileged user set
the backing snd_timer's hardware resolution to an arbitrary 64-bit value
via SNDRV_TIMER_IOCTL_CREATE. snd_utimer_create() only rejects zero.

When such a timer is bound to a sequencer queue, initialize_timer()
computes the tick period as

	tmr-&gt;ticks = 1000000000 / (r * freq);

where r is that user-controlled resolution and freq is the sequencer
update rate in Hz, clamped to MIN_FREQUENCY..MAX_FREQUENCY (10..6250).
A resolution of 2^63 makes the 64-bit product r * freq wrap to zero for
any even freq, including DEFAULT_FREQUENCY (1000), so the division faults
with a divide-by-zero.

The division runs under tmr-&gt;lock with interrupts disabled, so the oops
leaves the spinlock held and hangs the CPU. It is reachable by an
unprivileged user with access to /dev/snd/timer and /dev/snd/seq.

  Oops: divide error: 0000 [#1] SMP KASAN PTI
  CPU: 7 UID: 1000 PID: 456 Comm: alsa_seq_utimer Not tainted 7.2.0-rc4+
  RIP: 0010:initialize_timer.constprop.0+0x20a/0x2d0
   snd_seq_timer_start+0x15e/0x2b0
   snd_seq_control_queue+0x56f/0xba0
   snd_seq_write+0x3e0/0x730

Reject an overflowing product with check_mul_overflow() and fall back to
a single tick, which also avoids feeding a wrapped-but-nonzero divisor
(e.g. 2^63 * 1000 mod 2^64 == 0, or other resolutions wrapping to a small
value) into the period computation.

Fixes: 37745918e0e7 ("ALSA: timer: Introduce virtual userspace-driven timers")
Cc: &lt;stable@vger.kernel.org&gt;
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Norbert Szetei &lt;norbert@doyensec.com&gt;
Link: https://patch.msgid.link/DF8A3844-AD5E-4B8A-9CFC-BD83C212BA38@doyensec.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ALSA: pcm: wake linked drain waiters on unlink</title>
<updated>2026-08-09T18:25:13+00:00</updated>
<author>
<name>Norbert Szetei</name>
<email>norbert@doyensec.com</email>
</author>
<published>2026-07-28T12:50:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=2940cc3cf43c72126b74ee6376314c195382023a'/>
<id>urn:sha1:2940cc3cf43c72126b74ee6376314c195382023a</id>
<content type='text'>
commit f495b6c4c8594122918552c9be2b51eb71647cd9 upstream.

snd_pcm_drain() on a linked stream parks an on-stack wait entry on the
drained peer's runtime-&gt;sleep, and after schedule_timeout() removes it
only if that peer is still found in the caller's group.  If group
membership changes during the wait and the sleep ends by signal or
timeout (so autoremove_wake_function() does not run), finish_wait() is
skipped and snd_pcm_drain() returns with the entry still queued on that
stream's sleep list; a later wake_up() then walks a freed stack frame.
This is reachable by unlinking either the drained or the draining stream.

Unlike the close path (snd_pcm_drop() -&gt; snd_pcm_post_stop()),
snd_pcm_unlink() never wakes the sleep queues.  Wake every group member
under the group lock before the membership change, so a linked drainer is
released and drops its entry while the streams are still grouped.

The window was opened when snd_pcm_link_rwsem stopped being held across
the wait and the removal became conditional on group membership (see
Fixes). The later switch to finish_wait() kept that conditional removal,
so the signal/timeout case remained.

Fixes: f57f3df03a8e ("ALSA: pcm: More fine-grained PCM link locking")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Norbert Szetei &lt;norbert@doyensec.com&gt;
Link: https://patch.msgid.link/A0705100-D10B-4286-9980-0142ABEEAD51@doyensec.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ALSA: timer: don't re-enter an instance callback that is still running</title>
<updated>2026-08-03T09:21:57+00:00</updated>
<author>
<name>Norbert Szetei</name>
<email>norbert@doyensec.com</email>
</author>
<published>2026-07-20T07:09:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=1395327a96614885552bae5fbb650e6dd182d49b'/>
<id>urn:sha1:1395327a96614885552bae5fbb650e6dd182d49b</id>
<content type='text'>
commit 70d28bfcd6224eed75986b3b987b997e59643fa4 upstream.

The userspace-driven timer (utimer) TRIGGER ioctl calls
snd_timer_interrupt() directly with no serialization, so two threads
triggering the same utimer can run snd_timer_interrupt() on one
snd_timer concurrently.

snd_timer_process_callbacks() drops timer-&gt;lock around each instance
callback and marks the in-flight callback with the single
SNDRV_TIMER_IFLG_CALLBACK bit; snd_timer_close_locked() waits on that
bit to drain an in-flight callback before freeing the instance. The bit
cannot represent two concurrent callbacks: when a second interrupt
re-queues an instance whose callback is still running, both run at once,
the first to finish clears the bit, and the close-path drain then frees
the instance (and its callback_data) while the other callback is still
live - a use-after-free reachable by any user able to open
/dev/snd/timer, both via a user timer instance and via a sequencer queue
timer bound to the utimer.

snd_timer_interrupt() sets IFLG_CALLBACK before dropping timer-&gt;lock, so
a concurrent interrupt already observes it under the lock. Skip
re-queuing an instance (and its slaves) to the ack/sack list while its
callback is in flight; the accumulated pticks are delivered on the next
tick, so no event is lost.

Fixes: 37745918e0e7 ("ALSA: timer: Introduce virtual userspace-driven timers")
Cc: stable@vger.kernel.org
Suggested-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Norbert Szetei &lt;norbert@doyensec.com&gt;
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/6F9B6501-8E65-4265-B02C-7EFB240D1664@doyensec.com
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ALSA: timer: drain a slave's callback before its master detaches it</title>
<updated>2026-08-03T09:21:57+00:00</updated>
<author>
<name>Norbert Szetei</name>
<email>norbert@doyensec.com</email>
</author>
<published>2026-07-20T07:14:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=426c0ff1c433d6030610ad4f9375746dfe931caa'/>
<id>urn:sha1:426c0ff1c433d6030610ad4f9375746dfe931caa</id>
<content type='text'>
commit bdefe1346a8e6b8dc8593406dc2617e985fcbcab upstream.

snd_timer_close_locked() drains the closing instance's own in-flight
callback (IFLG_CALLBACK) before freeing it, but not its slaves'. When a
master instance is closed, remove_slave_links() clears each slave's
-&gt;timer; the slave's own close then reads timer == NULL and takes the
branch that skips the drain entirely (snd_timer_stop_slave() also no-ops
on a NULL timer). So a slave whose callback is still running when the
master is closed is freed underneath the live callback, leading to
use-after-free.

Drain the slaves too before remove_slave_links() severs them.
snd_timer_stop() has already taken this instance off the active list, so
no new slave callback can be queued. Take the slaves off the ack list so
a pending one can't fire either, then wait for any that is already in
flight.

Fixes: 37745918e0e7 ("ALSA: timer: Introduce virtual userspace-driven timers")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Norbert Szetei &lt;norbert@doyensec.com&gt;
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Link: https://patch.msgid.link/D26598EB-DBF7-4D76-9F71-8E4BD59822D4@doyensec.com
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ALSA: seq: close a re-opened queue timer in the destructor</title>
<updated>2026-08-03T09:21:57+00:00</updated>
<author>
<name>Norbert Szetei</name>
<email>norbert@doyensec.com</email>
</author>
<published>2026-07-14T08:29:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=6a10025c7fd09a7d2af37a3ae1da188569fce470'/>
<id>urn:sha1:6a10025c7fd09a7d2af37a3ae1da188569fce470</id>
<content type='text'>
commit 2c4dc0ed50b05cd847a4b34b8cebf0775f19aeb9 upstream.

queue_delete() closes the queue timer, then frees it. snd_seq_timer_close()
clears q-&gt;timer-&gt;timeri. snd_use_lock_sync() then drains borrowers, and
snd_seq_timer_delete() frees q-&gt;timer.

A borrower can re-open the timer inside that window. A SET_QUEUE_CLIENT
that took a queueptr() use_lock reference before the queue was unlinked
runs snd_seq_timer_open() after the close. Open refuses re-open only while
timeri is set, and the close just cleared it, so it re-opens timeri.

snd_seq_timer_delete() does not close that instance. Its snd_seq_timer_stop()
is a no-op, because running was cleared first. So it frees q-&gt;timer with the
instance still live. The queue is freed next.

The instance stays on the global timer with callback_data pointing at the
freed queue. A non-owner START on the unlocked queue arms it. The next tick
derefs the freed queue in snd_seq_timer_interrupt().

Reachable by an unprivileged user with access to /dev/snd/seq. No CAP and
no queue ownership required.

Close any lingering instance in the destructor. There, -&gt;timeri can no
longer change: the queue is unlinked and all use_lock borrowers have
drained, so no snd_seq_queue_use() can re-open it. Close it before clearing
q-&gt;timer. snd_timer_close() waits for any in-flight snd_seq_timer_interrupt()
to finish, and that callback still reads q-&gt;timer (via snd_seq_check_queue()),
so q-&gt;timer must stay valid until it drains.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Norbert Szetei &lt;norbert@doyensec.com&gt;
Link: https://patch.msgid.link/422FDB81-2A68-47C7-A22D-2D3301E2E86D@doyensec.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>ALSA: core: Fix unintuitive behavior of snd_power_ref_and_wait()</title>
<updated>2026-07-24T14:16:13+00:00</updated>
<author>
<name>Takashi Iwai</name>
<email>tiwai@suse.de</email>
</author>
<published>2026-06-14T09:05:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=7a59146cb9ade235eddd7326764524b7fb2b54bd'/>
<id>urn:sha1:7a59146cb9ade235eddd7326764524b7fb2b54bd</id>
<content type='text'>
[ Upstream commit b113a891252c3fa4fab11ec8c2894a22ecaf278c ]

snd_power_ref_and_wait() takes the power refcount and doesn't leave it
no matter whether it returns an error or not.  However, the majority
of callers don't expect but just returns without unreferencing in the
caller side upon errors.

For addressing the potential refcount unbalance, rather correct the
behavior of snd_power_ref_wait() to unreference upon returning an
error.

Note that the problem above is likely negligible; the function returns
an error only when the sound card is being shutdown, hence it doesn't
matter about the power refcount any longer at such a state.

Fixes: e94fdbd7b25d ("ALSA: control: Track in-flight control read/write/tlv accesses")
Reported-by: WenTao Liang &lt;vulab@iscas.ac.cn&gt;
Closes: https://lore.kernel.org/20260612022121.14329-1-vulab@iscas.ac.cn
Link: https://patch.msgid.link/20260614090507.772540-1-tiwai@suse.de
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>ALSA: seq: avoid stale FIFO cells during resize</title>
<updated>2026-07-24T14:16:13+00:00</updated>
<author>
<name>Cen Zhang</name>
<email>zzzccc427@gmail.com</email>
</author>
<published>2026-06-14T00:48:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=98a965cb1e767b54b6bbd831b6cea26f521a8f51'/>
<id>urn:sha1:98a965cb1e767b54b6bbd831b6cea26f521a8f51</id>
<content type='text'>
[ Upstream commit e546128291f8d688dcb931827e2efd2aa6c0734d ]

snd_seq_fifo_resize() still needs to publish the replacement pool
before it waits for FIFO users. A blocking snd_seq_read() holds
f-&gt;use_lock while it sleeps, so concurrent senders must be able to
queue to the new pool and wake that reader instead of failing against a
closing old pool.

However, snd_seq_fifo_event_in() duplicates an event before it takes
f-&gt;lock, and snd_seq_read() can dequeue a cell and later call
snd_seq_fifo_cell_putback() if copy_to_user() or
snd_seq_expand_var_event() fails. If resize swaps f-&gt;pool and detaches
oldhead in between, either path can relink an old-pool cell after the
snapshot. That stale cell sits outside the drained oldhead list, keeps
oldpool-&gt;counter elevated, and can leave snd_seq_pool_delete() waiting
for the retired pool to drain.

Keep the existing swap-before-wait ordering in snd_seq_fifo_resize(),
but reject stale cells before any FIFO relink. Revalidate event-in cells
under f-&gt;lock and retry them against the published replacement pool, and
free stale putback cells instead of linking them back into the FIFO.

The buggy scenario involves two paths, with each column showing the
order within that path:

resize path:                    relink path:
1. Allocate newpool.             1. Take f-&gt;use_lock.
2. Swap f-&gt;pool to newpool and   2. Duplicate or dequeue an old-pool
   detach oldhead.                  cell before oldpool closes.
3. Mark oldpool closing and      3. Reach a later relink point after
   wait for FIFO users.             resize published newpool.
4. Free oldhead and delete       4. Relink the old-pool cell after
   oldpool.                         resize detached oldhead.
                                 5. Drop f-&gt;use_lock.

The reproducer reports a resize ioctl blocked in the expected pool
teardown path:

signal: resize iteration=98 target_pool=4 exceeded 250ms
        (elapsed=251ms)
diagnostic: resize_tid=651 wchan=snd_seq_pool_done
diagnostic: resize_tid=651 stack=
  snd_seq_pool_done+0x5b/0x140
  snd_seq_pool_delete+0x7a/0x90
  snd_seq_fifo_resize+0x193/0x1e0
  snd_seq_ioctl_set_client_pool+0x214/0x260
  snd_seq_ioctl+0x119/0x540
  __x64_sys_ioctl+0xd1/0x120
  do_syscall_64+0xbb/0x2f0
  entry_SYSCALL_64_after_hwframe+0x77/0x7f

A second run with larger pools hit the same target path:

signal: resize iteration=32 target_pool=64 exceeded 250ms
        (elapsed=251ms)
diagnostic: resize_tid=663 wchan=snd_seq_pool_done
diagnostic: resize_tid=663 stack=
  snd_seq_pool_done+0x5b/0x140
  snd_seq_pool_delete+0x7a/0x90
  snd_seq_fifo_resize+0x193/0x1e0
  snd_seq_ioctl_set_client_pool+0x214/0x260
  snd_seq_ioctl+0x119/0x540
  __x64_sys_ioctl+0xd1/0x120
  do_syscall_64+0xbb/0x2f0
  entry_SYSCALL_64_after_hwframe+0x77/0x7f

Fixes: 2d7d54002e39 ("ALSA: seq: Fix race during FIFO resize")

Signed-off-by: Cen Zhang &lt;zzzccc427@gmail.com&gt;
Link: https://patch.msgid.link/20260614004801.3507773-2-zzzccc427@gmail.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>ALSA: seq: oss: Serialize readq reset state with q-&gt;lock</title>
<updated>2026-07-24T14:16:13+00:00</updated>
<author>
<name>Cen Zhang</name>
<email>zzzccc427@gmail.com</email>
</author>
<published>2026-06-14T00:48:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=287d506d4e0865918cec82bb1361f283a08c979b'/>
<id>urn:sha1:287d506d4e0865918cec82bb1361f283a08c979b</id>
<content type='text'>
[ Upstream commit 49ce92d207820f588b0406add82f053decfbe5d9 ]

snd_seq_oss_readq_clear() resets qlen, head, and tail without
q-&gt;lock even though the normal reader and producer paths serialize the
same ring state under that spinlock. A reset can therefore race
snd_seq_oss_readq_free() or snd_seq_oss_readq_put_event() and leave
stale records in the queue, drop freshly queued ones, or report the
wrong readiness after wakeup. KCSAN reports a data race between
snd_seq_oss_readq_clear() and snd_seq_oss_readq_free().

Take q-&gt;lock while clearing the ring and resetting input_time. Factor
the enqueue logic into a caller-locked helper so
snd_seq_oss_readq_put_timestamp() updates its suppression state under
the same lock instead of racing the reset path.

The buggy scenario involves two paths, with each column showing the
order within that path:

reset path:                      locked readq updater:
1. snd_seq_oss_reset() or        1. A reader or callback producer
   release reaches                  takes q-&gt;lock on the same queue.
   snd_seq_oss_readq_clear().
2. snd_seq_oss_readq_clear()     2. The updater tests or modifies
   resets qlen, head, tail,         qlen, head, and tail.
   and input_time.
3. snd_seq_oss_readq_clear()     3. The updater completes its
   wakes sleepers on                read-modify-write sequence.
   q-&gt;midi_sleep.
4. Without q-&gt;lock, the reset    4. The resulting ring state drives
   can overlap the locked           later reads and readiness.
   update.

KCSAN reports:

BUG: KCSAN: data-race in snd_seq_oss_readq_clear /
snd_seq_oss_readq_free

write to 0xffff8881069fe608 of 4 bytes by task 120516 on cpu 0:
  snd_seq_oss_readq_free+0x6c/0x80
  snd_seq_oss_read+0xcb/0x250
  odev_read+0x38/0x60
  vfs_read+0xff/0x600
  ksys_read+0xb4/0x140
  __x64_sys_read+0x46/0x60
  do_syscall_64+0xbb/0x2f0
  entry_SYSCALL_64_after_hwframe+0x77/0x7f

read to 0xffff8881069fe608 of 4 bytes by task 120517 on cpu 1:
  snd_seq_oss_readq_clear+0x1f/0x90
  snd_seq_oss_reset+0xa7/0xf0
  snd_seq_oss_ioctl+0x6f6/0x7e0
  odev_ioctl+0x56/0xc0
  __x64_sys_ioctl+0xd1/0x120
  do_syscall_64+0xbb/0x2f0
  entry_SYSCALL_64_after_hwframe+0x77/0x7f

value changed: 0x00000001 -&gt; 0x00000000

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")

Signed-off-by: Cen Zhang &lt;zzzccc427@gmail.com&gt;
Link: https://patch.msgid.link/20260614004801.3507773-1-zzzccc427@gmail.com
Signed-off-by: Takashi Iwai &lt;tiwai@suse.de&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
</feed>
