summaryrefslogtreecommitdiff
path: root/sound/core/seq
AgeCommit message (Collapse)Author
4 daysALSA: seq: Fix uninitialised heap leak in snd_seq_event_dup()HyeongJun An
snd_seq_event_dup() copies an incoming event into a pool cell and, in the UMP-enabled build, clears the trailing cell->ump.raw.extra word that the memcpy() did not cover. The guard deciding whether to clear it compares the copied size against sizeof(cell->event): memcpy(&cell->ump, event, size); if (size < sizeof(cell->event)) cell->ump.raw.extra = 0; For a legacy (non-UMP) event, size == sizeof(struct snd_seq_event) == sizeof(cell->event), so the condition is false and the extra word keeps stale data. The cell pool is allocated with kvmalloc() (not zeroed) and cells are reused via a free list, so that word holds uninitialised heap or leftover event data. When such a cell is delivered to a UMP client (client->midi_version > 0) that set SNDRV_SEQ_FILTER_NO_CONVERT -- so the legacy event reaches it unconverted -- snd_seq_read() reads it out as the larger struct snd_seq_ump_event and copies the stale word to user space, a 4-byte kernel heap infoleak to an unprivileged /dev/snd/seq client. Compare against sizeof(cell->ump) instead, so the trailing word is zeroed for every event shorter than the UMP cell. Fixes: 46397622a3fa ("ALSA: seq: Add UMP support") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-8 Signed-off-by: HyeongJun An <sammiee5311@gmail.com> Link: https://patch.msgid.link/20260623233841.853326-1-sammiee5311@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-06-14ALSA: seq: avoid stale FIFO cells during resizeCen Zhang
snd_seq_fifo_resize() still needs to publish the replacement pool before it waits for FIFO users. A blocking snd_seq_read() holds f->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->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->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->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->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->use_lock. 2. Swap f->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->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 <zzzccc427@gmail.com> Link: https://patch.msgid.link/20260614004801.3507773-2-zzzccc427@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-06-14ALSA: seq: oss: Serialize readq reset state with q->lockCen Zhang
snd_seq_oss_readq_clear() resets qlen, head, and tail without q->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->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->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->midi_sleep. 4. Without q->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 -> 0x00000000 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/20260614004801.3507773-1-zzzccc427@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-06-12ALSA: seq: Don't re-bounce the error eventTakashi Iwai
The error bouncing may fail again, and we have no check for re-bouncing. For avoiding the loop, add the event type check at bouncing, and stop re-bouncing if it's already a bounce error. Link: https://patch.msgid.link/20260612113350.407465-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-06-12ALSA: seq: Fix kernel heap address leak in bounce_error_event()HanQuan
The comment above bounce_error_event() documents that user clients should receive SNDRV_SEQ_EVENT_BOUNCE with the original event embedded as variable-length data, while kernel clients should receive SNDRV_SEQ_EVENT_KERNEL_ERROR with a quoted kernel pointer. However, the implementation unconditionally uses SNDRV_SEQ_EVENT_KERNEL_ERROR with data.quote.event set to the raw struct snd_seq_event pointer for all clients. When a bounce error event is delivered to a USER_CLIENT via snd_seq_read(), the kernel heap address in data.quote.event is exposed to userspace through copy_to_user() in the fixed-length branch. This is a distinct leak path from the one addressed by commit 705dd6dcbc0e ("ALSA: seq: Clear variable event pointer on read"), which sanitizes data.ext.ptr in the variable-length branch of snd_seq_read(). The bounce_error_event() leak uses fixed-length events that take the else branch where no sanitization occurs. Differentiate the bounce event by client type. For USER_CLIENT, send SNDRV_SEQ_EVENT_BOUNCE with SNDRV_SEQ_EVENT_LENGTH_VARIABLE and data.ext pointing to the original event. The variable-length path in snd_seq_event_dup() copies the event data into chained cells, and snd_seq_expand_var_event() copies only the content -- never the pointer -- to userspace. For KERNEL_CLIENT, keep the existing SNDRV_SEQ_EVENT_KERNEL_ERROR behavior with the quoted pointer. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: HanQuan <eilaimemedsnaimel@gmail.com> Link: https://patch.msgid.link/20260612103222.2528305-1-eilaimemedsnaimel@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-06-10ALSA: timer: Manage timer object with krefTakashi Iwai
So far we've tried to address UAFs in ALSA timer code by applying the locks at various places, but the fundamental problem is that the timer object may be released while the belonging timer instance objects are still present and accessing to it. This patch is a more proper fix to address that issue, namely, by refcounting and keeping the timer object. The basic implementation is to use kref for the refcount of the timer object, and take/release the reference at assigning/releasing the instance, as well as at referring from ioctls or ALSA sequencer code. The reference from ioctl or ALSA sequencer is abstracted with snd_timeri_timer auto-cleanup. Note that this change assumes that the code already took the fix commit da3039e91d1f ("ALSA: timer: Forcibly close timer instances at closing"); otherwise the refcount may be unbalanced when the timer is freed while slave instances are still present. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20260609115100.806869-2-tiwai@suse.de
2026-06-07Merge branch 'for-linus' into for-nextTakashi Iwai
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-06-07ALSA: seq: Clear variable event pointer on readKyle Zeng
snd_seq_read() copies a queued variable-length event header to userspace before expanding the payload. Queued variable-length events use SNDRV_SEQ_EXT_CHAINED internally, and data.ext.ptr points at the first extension cell. The read side strips SNDRV_SEQ_EXT_* bits from data.ext.len before the copy, but it leaves data.ext.ptr untouched. A userspace sequencer client can therefore write a direct variable event to itself and read back the extension-cell kernel address from the returned header. Clear the temporary header pointer before copy_to_user(). The original queued event remains unchanged and is still passed to snd_seq_expand_var_event(), so payload expansion keeps using the internal chain. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Kyle Zeng <kylebot@openai.com> Link: https://patch.msgid.link/20260607004129.61345-1-kylebot@openai.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-06-06ALSA: seq: Fix partial userptr event expansionHyeongJun An
snd_seq_expand_var_event_at() clamps the number of bytes to copy to the remaining variable-event length, but passes the original buffer size to expand_var_event(). For SNDRV_SEQ_EXT_USRPTR events, expand_var_event() copies exactly the size argument from userspace. On the final chunk, when the remaining event data is shorter than the caller's buffer, this can read past the declared event data and can spuriously fail with -EFAULT if the extra bytes cross an unmapped page. Pass the clamped length instead. The chained and kernel-backed paths already reclamp in dump_var_event(), but the user-pointer path handles the size directly. Fixes: ea46f79709b6 ("ALSA: seq: Add snd_seq_expand_var_event_at() helper") Signed-off-by: HyeongJun An <sammiee5311@gmail.com> Link: https://patch.msgid.link/20260606040913.230213-1-sammiee5311@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-06-05ALSA: seq: dummy: fix UMP event stack overreadKyle Zeng
The dummy sequencer port forwards events by copying an incoming struct snd_seq_event into a stack temporary, rewriting source and destination, and dispatching the temporary to subscribers. That legacy event storage is smaller than struct snd_seq_ump_event. When a UMP event reaches the dummy client, the copy leaves the UMP flag set but only provides legacy-sized stack storage. The subscriber delivery path then uses snd_seq_event_packet_size() and copies a UMP-sized packet from that stack object, reading past the end of the temporary. Use the existing union __snd_seq_event storage and copy the packet size reported for the incoming event before rewriting the common routing fields. This preserves the full UMP packet for UMP events while keeping legacy event handling unchanged. Fixes: 32cb23a0f911 ("ALSA: seq: dummy: Allow UMP conversion") Signed-off-by: Kyle Zeng <kylebot@openai.com> Link: https://patch.msgid.link/20260605080204.32045-1-kylebot@openai.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-06-04ALSA: seq: oss: Use scoped cleanup for temporary MIDI use lockCássio Gabriel
The OSS sequencer write and out-of-band paths may receive a temporary snd_use_lock_t reference from snd_seq_oss_process_event(). This was added to keep MIDI device data alive until events with embedded SysEx data are dispatched. Use a scoped cleanup helper for that temporary reference. This keeps the lifetime rule local to the variable declaration and avoids future missing snd_use_lock_free() paths if these event handling paths gain more exits. No functional change is intended. Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20260604-alsa-scoped-cleanups-v1-3-10c43152a728@gmail.com
2026-06-02ALSA: seq: oss: Reject reads that cannot fit the next eventCássio Gabriel
snd_seq_oss_read() checks whether the next queued OSS sequencer event fits in the remaining userspace buffer before removing it from the read queue. The check is inverted. It currently stops when the event is smaller than the remaining buffer, so a normal 4-byte event is not copied for an 8-byte read buffer. Conversely, an 8-byte event can be copied for a smaller read count. Break only when the remaining userspace buffer is smaller than the next event, and report -EINVAL if no complete event has been copied. This prevents an undersized read from looking like end-of-file while leaving the event queued for a later read with a large enough buffer. Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com> Link: https://patch.msgid.link/20260602-alsa-seq-oss-read-size-check-v1-1-10e59b1742e0@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-06-02ALSA: seq: Restore created port information after insertionCássio Gabriel
Commit 2ee646353cd5 ("ALSA: seq: Register kernel port with full information") split sequencer port creation from list insertion so a port can be filled before it becomes visible. However, snd_seq_ioctl_create_port() still copies port->addr back to the ioctl argument before snd_seq_insert_port() assigns the final port number. A successful SNDRV_SEQ_IOCTL_CREATE_PORT without SNDRV_SEQ_PORT_FLG_GIVEN_PORT can therefore report port -1 to userspace. Move the ioctl address copy after successful insertion, and keep the default "port-%d" name assignment from overwriting a caller-provided port name. This restores the observable behavior from before the split while keeping the port populated before publication. Fixes: 2ee646353cd5 ("ALSA: seq: Register kernel port with full information") Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com> Link: https://patch.msgid.link/20260602-alsa-seq-create-port-info-fix-v1-1-eec0280131e9@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-27ALSA: seq: midi: Serialize output teardown with event_inputZhang Cen
event_process_midi() borrows msynth->output_rfile.output and then passes the substream to dump_midi() and snd_rawmidi_kernel_write() without synchronizing with the output open/close transition. midisynth_use() also publishes output_rfile before snd_rawmidi_output_params() has finished. The last midisynth_unuse() can therefore release the same rawmidi file and free substream->runtime before snd_rawmidi_kernel_write1() takes its runtime buffer reference. That leaves the event_input path using a stale substream or runtime and can end in a NULL-deref or use-after-free. Fix this with two pieces of synchronization. Keep a short IRQ-safe spinlock only for publishing or clearing output_rfile and for pairing the output snapshot with an snd_use_lock_t reference. Once event_process_midi() has taken that in-flight reference, it drops the spinlock before calling snd_seq_dump_var_event(), dump_midi(), or snd_rawmidi_kernel_write(). midisynth_unuse() now detaches the visible rawmidi file under the same spinlock, waits for the in-flight writers to drain, and only then drains and releases the saved file. midisynth_use() likewise opens into a local snd_rawmidi_file and publishes it only after snd_rawmidi_output_params() succeeds. The buggy scenario involves two paths, with each column showing the order within that path: event_input path: last unuse path: 1. event_process_midi() snapshots 1. midisynth_unuse() starts output_rfile.output. tearing down output_rfile. 2. dump_midi() reaches 2. snd_rawmidi_kernel_release() snd_rawmidi_kernel_write() closes the output file. before runtime is pinned. 3. close_substream() frees 3. The callback keeps using substream->runtime. the borrowed substream. Validation reproduced this kernel report: KASAN null-ptr-deref in snd_rawmidi_kernel_write1+0x56/0x360 RIP: 0033:0x7fde7dd0837f RIP: 0010:snd_rawmidi_kernel_write1+0x56/0x360 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Assisted-by: Codex:gpt-5.5 Signed-off-by: Zhang Cen <rollkingzzc@gmail.com> Link: https://patch.msgid.link/20260527062948.3614025-1-rollkingzzc@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-27ALSA: seq: oss: Fix UAF at handling events with embedded SysEx dataTakashi Iwai
The OSS sequencer processes the input MIDI bytes into a sequencer event to be dispatched later (in snd_seq_oss_midi_putc() called from snd_seq_oss_process_event()). When it's a SysEx data, the event record contains data.ext.ptr pointer to the original SysEx bytes, and the referred data is copied into the pool afterwards at dispatching. The problem is that, if the sequencer port gets closed concurrently before the dispatch, the OSS sequencer core also releases the resources (in snd_seq_oss_midi_check_exit_port()), while the pending event may hold a stale pointer, eventually leading to a UAF at a later dispatch. Fortunately, there is already a refcounting mechanism (snd_use_lock_t) for the OSS MIDI device access, and for addressing the issue above, we just need to extend the refcount until the event gets dispatched. This patch extends snd_seq_oss_process_event() to give back the refcount object, which is in turn released after calling the sequencer dispatcher with the given event in the caller side. According to the original report, KASAN report as below: KASAN slab-use-after-free in snd_seq_event_dup+0x40c/0x470 RIP: 0033:0x7f2cb66a6340 Read of size 6 Call trace: dump_stack_lvl+0x73/0xb0 (?:?) print_report+0xd1/0x650 (?:?) srso_alias_return_thunk+0x5/0xfbef5 (?:?) __virt_addr_valid+0x1a7/0x340 (?:?) kasan_complete_mode_report_info+0x64/0x200 (?:?) kasan_report+0xf7/0x130 (?:?) snd_seq_event_dup+0x40c/0x470 (?:?) kasan_check_range+0x10c/0x1c0 (?:?) __asan_memcpy+0x27/0x70 (?:?) snd_seq_event_dup+0x9/0x470 (?:?) snd_seq_client_enqueue_event+0x139/0x240 (?:?) _raw_spin_unlock_irqrestore+0x4b/0x60 (?:?) snd_seq_kernel_client_enqueue+0x102/0x120 (?:?) snd_seq_oss_write+0x416/0x4e0 (?:?) apparmor_file_permission+0x20/0x30 (?:?) odev_write+0x3b/0x60 (?:?) vfs_write+0x1ce/0x850 (?:?) lock_release+0xc8/0x2a0 (?:?) __kasan_check_write+0x18/0x20 (?:?) __mutex_unlock_slowpath+0x129/0x510 (?:?) ksys_write+0xe1/0x180 (?:?) mutex_unlock+0x16/0x20 (?:?) odev_ioctl+0x65/0xc0 (?:?) __x64_sys_write+0x46/0x60 (?:?) x64_sys_call+0x7d/0x20d0 (?:?) do_syscall_64+0xc1/0x360 (arch/x86/entry/syscall_64.c:87) entry_SYSCALL_64_after_hwframe+0x77/0x7f (?:?) Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-and-tested-by: Zhang Cen <rollkingzzc@gmail.com> Closes: https://lore.kernel.org/20260521233900.478153-1-rollkingzzc@gmail.com Link: https://patch.msgid.link/20260526152843.617503-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-26ALSA: seq: Remove arbitrary prioq insertion limitCássio Gabriel
The sequencer priority queue insertion path uses a hardcoded traversal limit of 10000 entries. The value is intended to catch a corrupted list, but it also becomes a real limit for valid queues. The event pool limit is per client, while a sequencer queue can be shared by multiple clients. A queue can therefore legitimately contain more than 10000 events. In that case, inserting an event that has to be placed past the arbitrary limit fails with -EINVAL. Use the queue's own cell count as the traversal bound instead. This keeps the protection against inconsistent list accounting or cyclic lists without rejecting valid large queues. Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com> Link: https://patch.msgid.link/20260525-alsa-seq-prioq-limit-v1-1-16c348df5ff7@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-25ALSA: core: Mark some variables as __ro_after_initLen Bao
Some variables in the 'ALSA/core' are initialized only during the init phase in the '__init' functions and never changed. So, mark them as __ro_after_init to reduce the attack surface. Signed-off-by: Len Bao <len.bao@gmx.us> Link: https://patch.msgid.link/20260524162914.47764-1-len.bao@gmx.us Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-25Merge branch 'for-linus' into for-nextTakashi Iwai
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-20ALSA: seq: Serialize UMP output teardown with event_inputZhang Cen
seq_ump_process_event() borrows client->out_rfile.output without synchronizing with the first-open and last-close transition in seq_ump_client_open() and seq_ump_client_close(). The last output unuse can therefore drop opened[STR_OUT] to zero and release the rawmidi file while an in-flight event_input callback is still inside snd_rawmidi_kernel_write(). That leaves the rawmidi substream runtime exposed to teardown before the write path has taken its own buffer reference. Add a per-client rwlock for the event_input-visible output file. Publish a newly opened output file under the write side, and hold the read side from the output lookup through snd_rawmidi_kernel_write(). The last output close copies and clears the visible output file under the write side, then drops the lock and releases the saved rawmidi file. Use IRQ-safe rwlock guards because event_input can also be reached from atomic sequencer delivery. The buggy scenario involves two paths, with each column showing the order within that path: path A label: event_input path path B label: last unuse path 1. seq_ump_process_event() reads 1. seq_ump_client_close() client->out_rfile.output. drops opened[STR_OUT] to zero. 2. snd_rawmidi_kernel_write1() 2. snd_rawmidi_kernel_release() has not yet pinned runtime. closes the output file. 3. The writer continues using 3. close_substream() frees the borrowed substream. substream->runtime. This keeps the output substream and runtime alive for the full event_input write while keeping rawmidi release outside the rwlock. KASAN reproduced this as a slab-use-after-free in snd_rawmidi_kernel_write1(), with allocation through seq_ump_use()/snd_seq_port_connect() and free through seq_ump_unuse()/snd_seq_port_disconnect(). Suggested-by: Takashi Iwai <tiwai@suse.de> Validation reproduced this kernel report: KASAN slab-use-after-free in snd_rawmidi_kernel_write1+0x9d/0x400 RIP: 0033:0x7f5528af837f Read of size 8 Call trace: dump_stack_lvl+0x73/0xb0 (?:?) print_report+0xd1/0x650 (?:?) srso_alias_return_thunk+0x5/0xfbef5 (?:?) __virt_addr_valid+0x1a7/0x340 (?:?) kasan_complete_mode_report_info+0x64/0x200 (?:?) kasan_report+0xf7/0x130 (?:?) snd_rawmidi_kernel_write1+0x9d/0x400 (?:?) __asan_load8+0x82/0xb0 (?:?) update_stack_state+0x1ef/0x2d0 (?:?) snd_rawmidi_kernel_write+0x1a/0x20 (?:?) seq_ump_process_event+0xd4/0x120 (sound/core/seq/seq_ump_client.c:82) __snd_seq_deliver_single_event+0x8a/0xe0 (?:?) snd_seq_deliver_from_ump+0x2b2/0xd60 (?:?) lock_acquire+0x14e/0x2e0 (?:?) find_held_lock+0x31/0x90 (?:?) snd_seq_port_use_ptr+0xa6/0xe0 (?:?) __kasan_check_write+0x18/0x20 (?:?) do_raw_read_unlock+0x32/0xa0 (?:?) _raw_read_unlock+0x26/0x50 (?:?) snd_seq_deliver_single_event+0x45c/0x4b0 (?:?) snd_seq_deliver_event+0x10d/0x1b0 (?:?) snd_seq_client_enqueue_event+0x192/0x240 (?:?) snd_seq_write+0x2cd/0x450 (?:?) apparmor_file_permission+0x20/0x30 (?:?) security_file_permission+0x51/0x60 (?:?) vfs_write+0x1ce/0x850 (?:?) __fget_files+0x12b/0x220 (?:?) lock_release+0xc8/0x2a0 (?:?) __rcu_read_unlock+0x74/0x2d0 (?:?) __fget_files+0x135/0x220 (?:?) ksys_write+0x15a/0x180 (?:?) rcu_is_watching+0x24/0x60 (?:?) __x64_sys_write+0x46/0x60 (?:?) x64_sys_call+0x7d/0x20d0 (?:?) do_syscall_64+0xc1/0x360 (arch/x86/entry/syscall_64.c:87) entry_SYSCALL_64_after_hwframe+0x77/0x7f (?:?) Fixes: 81fd444aa371 ("ALSA: seq: Bind UMP device") Signed-off-by: Zhang Cen <rollkingzzc@gmail.com> Link: https://patch.msgid.link/20260520103249.3048345-1-rollkingzzc@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-20ALSA: seq: Register kernel port with full informationTakashi Iwai
The current ALSA sequencer core tries to register the new kernel sequencer port on the list at first, then fill up the port information. This means that user-space may sneak the wrong information before the actual data is filled, which isn't ideal. Although the user-space should try to query the port info after the port registration notification is sent out, it'd be still better to have a port available with the full info from the beginning. This patch changes the sequencer port creation and registration procedure; now split to two steps, for creation and insertion, and the port is registered after the information is filled. Link: https://sashiko.dev/#/patchset/20260518194023.1667857-1-maoyixie.tju%40gmail.com Link: https://patch.msgid.link/20260519094254.465041-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-19Merge branch 'for-linus' into for-nextTakashi Iwai
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-19ALSA: seq: avoid past-the-end iterator in snd_seq_create_port()Maoyi Xie
snd_seq_create_port() walks client->ports_list_head looking for the ordered insertion point and on loop fall-through passes &p->list to list_add_tail(): list_for_each_entry(p, &client->ports_list_head, list) { if (p->addr.port == port) { kfree(new_port); return -EBUSY; } if (p->addr.port > num) break; ... } list_add_tail(&new_port->list, &p->list); When the loop walks all entries without break (e.g., the new port sorts last), p is past-the-end. &p->list aliases &client->ports_list_head (the list head) via container_of offset cancellation, so the insert lands at the list tail. That is the intended behaviour, but the access is undefined per C11 even though it works in practice. Track an explicit insert_before pointer initialised to the list head and overwritten to &p->list only when the loop breaks early. The observable behaviour is unchanged. Fixes: 9244b2c3079f ("[ALSA] alsa core: convert to list_for_each_entry*") Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com> Link: https://patch.msgid.link/20260518194023.1667857-3-maoyixie.tju@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-15Merge branch 'for-linus' into for-nextTakashi Iwai
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-15ALSA: seq: Use flexible array for MIDI channelsRosen Penev
Store MIDI channel entries in the MIDI channel set allocation instead of allocating them separately. This ties the channel array lifetime directly to the channel set, removes a separate allocation failure path, and lets __counted_by() describe the array bounds. Move the embedded emux channel set to the end of its containing structure so it can carry the flexible array. Assisted-by: Codex:GPT-5.5 Signed-off-by: Rosen Penev <rosenp@gmail.com> Link: https://patch.msgid.link/20260511075447.445350-1-rosenp@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-06ALSA: seq: Fix UMP group 16 filteringCássio Gabriel
The sequencer UAPI defines group_filter as an unsigned int bitmap. Bit 0 filters groupless messages and bits 1-16 filter UMP groups 1-16. The internal snd_seq_client storage is only unsigned short, so bit 16 is truncated when userspace sets the filter. The same truncation affects the automatic UMP client filter used to avoid delivery to inactive groups, so events for group 16 cannot be filtered. Store the internal bitmap as unsigned int and keep both userspace-provided and automatically generated values limited to the defined UAPI bits. Fixes: d2b706077792 ("ALSA: seq: Add UMP group filter") Cc: stable@vger.kernel.org Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com> Link: https://patch.msgid.link/20260506-alsa-seq-ump-group16-filter-v1-1-b75160bf6993@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-05-04ALSA: seq: oss/rw: allocate evrec with main structRosen Penev
Use a flexible array member to simplify allocation slightly. Add the header as flexible array members require full definitions. Remove null check and just kfree. The former is not needed. Signed-off-by: Rosen Penev <rosenp@gmail.com> Link: https://patch.msgid.link/20260430210413.31185-1-rosenp@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-03-27ALSA: seq_oss: return full count for successful SEQ_FULLSIZE writesCássio Gabriel
snd_seq_oss_write() currently returns the raw load_patch() callback result for SEQ_FULLSIZE events. That callback is documented as returning 0 on success and -errno on failure, but snd_seq_oss_write() is the file write path and should report the number of user bytes consumed on success. Some in-tree backends also return backend-specific positive values, which can still be shorter than the original write size. Return the full byte count for successful SEQ_FULLSIZE writes. Preserve negative errors and convert any nonnegative completion to the original count. Cc: stable@vger.kernel.org Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com> Link: https://patch.msgid.link/20260324-alsa-seq-oss-fullsize-write-return-v1-1-66d448510538@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-03-27ALSA: core/seq: Optimize the return logic in cc_ev_to_ump_midi2songxiebing
There are multiple early return branches within the func, and compiler optimizations(such as -O2/-O3)lead to abnormal stack frame analysis - objtool cannot comfirm that the stack frames of all branches can be correctly restored, thus generating false warnings. Below: >> sound/core/seq/seq_ump_convert.o: warning: objtool: cc_ev_to_ump_midi2+0x589: return with modified stack frame So we modify it by uniformly returning at the and of the function. Signed-off-by: songxiebing <songxiebing@kylinos.cn> Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202503200535.J3hAvcjw-lkp@intel.com/ Link: https://patch.msgid.link/20260325015119.175835-1-songxiebing@kylinos.cn Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-02-22Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL usesKees Cook
Conversion performed via this Coccinelle script: // SPDX-License-Identifier: GPL-2.0-only // Options: --include-headers-for-types --all-includes --include-headers --keep-comments virtual patch @gfp depends on patch && !(file in "tools") && !(file in "samples")@ identifier ALLOC = {kmalloc_obj,kmalloc_objs,kmalloc_flex, kzalloc_obj,kzalloc_objs,kzalloc_flex, kvmalloc_obj,kvmalloc_objs,kvmalloc_flex, kvzalloc_obj,kvzalloc_objs,kvzalloc_flex}; @@ ALLOC(... - , GFP_KERNEL ) $ make coccicheck MODE=patch COCCI=gfp.cocci Build and boot tested x86_64 with Fedora 42's GCC and Clang: Linux version 6.19.0+ (user@host) (gcc (GCC) 15.2.1 20260123 (Red Hat 15.2.1-7), GNU ld version 2.44-12.fc42) #1 SMP PREEMPT_DYNAMIC 1970-01-01 Linux version 6.19.0+ (user@host) (clang version 20.1.8 (Fedora 20.1.8-4.fc42), LLD 20.1.8) #1 SMP PREEMPT_DYNAMIC 1970-01-01 Signed-off-by: Kees Cook <kees@kernel.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21Convert more 'alloc_obj' cases to default GFP_KERNEL argumentsLinus Torvalds
This converts some of the visually simpler cases that have been split over multiple lines. I only did the ones that are easy to verify the resulting diff by having just that final GFP_KERNEL argument on the next line. Somebody should probably do a proper coccinelle script for this, but for me the trivial script actually resulted in an assertion failure in the middle of the script. I probably had made it a bit _too_ trivial. So after fighting that far a while I decided to just do some of the syntactically simpler cases with variations of the previous 'sed' scripts. The more syntactically complex multi-line cases would mostly really want whitespace cleanup anyway. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21Convert 'alloc_obj' family to use the new default GFP_KERNEL argumentLinus Torvalds
This was done entirely with mindless brute force, using git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' | xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/' to convert the new alloc_obj() users that had a simple GFP_KERNEL argument to just drop that argument. Note that due to the extreme simplicity of the scripting, any slightly more complex cases spread over multiple lines would not be triggered: they definitely exist, but this covers the vast bulk of the cases, and the resulting diff is also then easier to check automatically. For the same reason the 'flex' versions will be done as a separate conversion. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21treewide: Replace kmalloc with kmalloc_obj for non-scalar typesKees Cook
This is the result of running the Coccinelle script from scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to avoid scalar types (which need careful case-by-case checking), and instead replace kmalloc-family calls that allocate struct or union object instances: Single allocations: kmalloc(sizeof(TYPE), ...) are replaced with: kmalloc_obj(TYPE, ...) Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...) are replaced with: kmalloc_objs(TYPE, COUNT, ...) Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...) are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...) (where TYPE may also be *VAR) The resulting allocations no longer return "void *", instead returning "TYPE *". Signed-off-by: Kees Cook <kees@kernel.org>
2025-12-17ALSA: seq: Relax __free() variable declarationsTakashi Iwai
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups. Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations. Note that there is a remaining __free() with NULL initialization; it's because of the non-trivial code conditionally assigning the data. Fixes: 04a86185b785 ("ALSA: seq: Clean up queue locking with auto cleanup") Fixes: 0869afc958a0 ("ALSA: seq: Clean up port locking with auto cleanup") Fixes: 99e16633958b ("ALSA: seq: Use auto-cleanup for client refcounting") Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20251216140634.171890-7-tiwai@suse.de
2025-12-17ALSA: seq: oss: Relax __free() variable declarationsTakashi Iwai
We used to have a variable declaration with __free() initialized with NULL. This was to keep the old coding style rule, but recently it's relaxed and rather recommends to follow the new rule to declare in place of use for __free() -- which avoids potential deadlocks or UAFs with nested cleanups. Although the current code has no bug, per se, let's follow the new standard and move the declaration to the place of assignment (or directly assign the allocated result) instead of NULL initializations. Fixes: 80ccbe91adab ("ALSA: seq: oss/synth: Clean up with guard and auto cleanup") Fixes: 895a46e034f9 ("ALSA: seq: oss/midi: Cleanup with guard and auto-cleanup") Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20251216140634.171890-6-tiwai@suse.de
2025-12-14ALSA: seq: oss: Convert to snd_seq bus probe mechanismUwe Kleine-König
The snd_seq bus got a dedicated probe function. Make use of that. This fixes a runtime warning about the driver needing to be converted to the bus probe method. Note that the remove callback returns void now. The actual return value was ignored before (see device_remove() in drivers/base/dd.c), so there is no problem introduced by converting `return -EINVAL` to `return`. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/affb5a7107e9d678ce85dc7f0b87445928cd6b94.1765283601.git.u.kleine-koenig@baylibre.com
2025-12-14ALSA: seq: ump: Convert to snd_seq bus probe mechanismUwe Kleine-König
The snd_seq bus got a dedicated probe function. Make use of that. This fixes a runtime warning about the driver needing to be converted to the bus probe method. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/054f1a0536228ccfe5f539ce854804f789f2ee64.1765283601.git.u.kleine-koenig@baylibre.com
2025-12-14ALSA: seq: midi: Convert to snd_seq bus probe mechanismUwe Kleine-König
The snd_seq bus got a dedicated probe function. Make use of that. This fixes a runtime warning about the driver needing to be converted to the bus probe method. Note that the remove callback returns void now. The actual return value was ignored before (see device_remove() in drivers/base/dd.c), so there is no problem introduced by converting `return -ENODEV` to `return`. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/054ae56db6b55eea60c8aa8f9633e8d3d180cb09.1765283601.git.u.kleine-koenig@baylibre.com
2025-09-17ALSA: seq: Fix KCSAN data-race warning at snd_seq_fifo_poll_wait()Takashi Iwai
snd_seq_fifo_poll_wait() evaluates f->cells without locking after poll_wait(), and KCSAN doesn't like it as it appears to be a data-race. Although this doesn't matter much in practice as the value is volatile, it's still better to address it for the mind piece. Wrap it with f->lock spinlock for avoiding the potential data race. Reported-by: syzbot+c3dbc239259940ededba@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=c3dbc239259940ededba Signed-off-by: Takashi Iwai <tiwai@suse.de>
2025-08-29ALSA: seq: oss/rw: Cleanup with guardTakashi Iwai
Replace the manual spin lock/unlock pairs with guard() for code simplification. Only code refactoring, and no behavior change. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250827080520.7544-12-tiwai@suse.de
2025-08-29ALSA: seq: oss/synth: Clean up with guard and auto cleanupTakashi Iwai
Use the auto-cleanup for the refcount management of seq_oss_synth object. The explicit call of snd_use_lock_free() is dropped by the magic __free(seq_oss_synth) attribute. Along with that, replace the manual mutex and spin locks with guard(). Only code refactoring, and no behavior change. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250827080520.7544-11-tiwai@suse.de
2025-08-29ALSA: seq: oss/midi: Cleanup with guard and auto-cleanupTakashi Iwai
Use the auto-cleanup for the refcount management of seq_oss_midi object. The explicit call of snd_use_lock_free() is dropped by the magic __free(seq_oss_midi) attribute. Along with that, replace the manual mutex and spin locks with guard(). Only code refactoring, and no behavior change. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250827080520.7544-10-tiwai@suse.de
2025-08-29ALSA: seq: oss: Clean up core code with guard()Takashi Iwai
Replace the manual mutex lock/unlock pairs with guard() for code simplification. Only code refactoring, and no behavior change. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250827080520.7544-9-tiwai@suse.de
2025-08-29ALSA: seq: Clean up fifo locking with guardTakashi Iwai
Yet more cleanup, now for seq_fifo.c about its refcount calls; the manual refcount calls (either snd_use_lock_*() or snd_seq_fifo_lock()) are replaced with guard(snd_seq_fifo). Only code refactoring, and no behavior change. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250827080520.7544-8-tiwai@suse.de
2025-08-29ALSA: seq: Clean up queue locking with auto cleanupTakashi Iwai
Yet more cleanup with the auto-cleanup macro: now we replace the queuefree() calls with the magic pointer attribute __free(snd_seq_queue). Only code refactoring, and no behavior change. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250827080520.7544-7-tiwai@suse.de
2025-08-29ALSA: seq: Clean up port locking with auto cleanupTakashi Iwai
Like the previous change in seq_clientmgr.c, introduce a new auto-cleanup macro for the snd_seq_port_unlock(), and apply it appropriately. Only code refactoring, and no behavior change. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250827080520.7544-6-tiwai@suse.de
2025-08-29ALSA: seq: Use auto-cleanup for client refcountingTakashi Iwai
The current code manages the refcount of client in a way like: snd_seq_client *client; client = clientptr(id); .... snd_seq_client_unlock(client); Now we introduce an auto-cleanup macro to manage the unlock implicitly, namely, the above will be replaced like: snd_seq_client *client __free(snd_seq_client) = NULL; client = clientptr(id); and we can forget the unref call. A part of the code in snd_seq_deliver_single_event() is factored out to a function, so that the auto-cleanups can be applied cleanly. This also allows us to replace some left mutex lock/unlock with guard(), and also reduce scoped_guard() to the normal guard(), too. Only code refactoring, and no behavior change. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250827080520.7544-5-tiwai@suse.de
2025-08-29ALSA: seq: Use guard() for mutex and rwsem locksTakashi Iwai
There are a few manual calls of mutex and rwsem lock/unlock pairs in seq_clientmngr.c, and those can be replaced nicely with guard(). Only code refactoring, and no behavior change. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250827080520.7544-4-tiwai@suse.de
2025-08-29ALSA: seq: Clean up spin lock with guard()Takashi Iwai
Use guard() for spin locks to manage the sequencer client locking. The code about the refcounting was modified with the new snd_seq_client_ref() and *_unref() helpers instead of the ugly goto, too. Only code refactoring, and no behavior change. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250827080520.7544-3-tiwai@suse.de
2025-08-29ALSA: seq: Simplify internal command operation from OSS layerTakashi Iwai
snd_seq_client_ioctl_lock() and *_unlock() are used only from a single function of the OSS layer, and it's just to wrap the call of snd_seq_kernel_client_ctl(). Provide another variant of snd_seq_kernel_client_ctl() that takes the locks internally and drop the ugly snd_seq_client_ioctl_lock() and *_unlock() implementations, instead. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250827080520.7544-2-tiwai@suse.de
2025-07-11ALSA: seq: Use safer strscpy() instead of strcpy()Takashi Iwai
Use a safer function strscpy() instead of strcpy() for copying to arrays. Only idiomatic code replacement, and no functional changes. Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20250710100727.22653-4-tiwai@suse.de