mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
queue_delete() closes the queue timer, then frees it. snd_seq_timer_close()
clears q->timer->timeri. snd_use_lock_sync() then drains borrowers, and
snd_seq_timer_delete() frees q->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->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, ->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->timer. snd_timer_close() waits for any in-flight snd_seq_timer_interrupt()
to finish, and that callback still reads q->timer (via snd_seq_check_queue()),
so q->timer must stay valid until it drains.
Fixes:
|
||
|---|---|---|
| .. | ||
| oss | ||
| Kconfig | ||
| Makefile | ||
| seq_clientmgr.c | ||
| seq_clientmgr.h | ||
| seq_compat.c | ||
| seq_dummy.c | ||
| seq_fifo.c | ||
| seq_fifo.h | ||
| seq_info.c | ||
| seq_info.h | ||
| seq_lock.c | ||
| seq_lock.h | ||
| seq_memory.c | ||
| seq_memory.h | ||
| seq_midi_emul.c | ||
| seq_midi_event.c | ||
| seq_midi.c | ||
| seq_ports.c | ||
| seq_ports.h | ||
| seq_prioq.c | ||
| seq_prioq.h | ||
| seq_queue.c | ||
| seq_queue.h | ||
| seq_system.c | ||
| seq_system.h | ||
| seq_timer.c | ||
| seq_timer.h | ||
| seq_ump_client.c | ||
| seq_ump_convert.c | ||
| seq_ump_convert.h | ||
| seq_virmidi.c | ||
| seq.c | ||