summaryrefslogtreecommitdiff
path: root/sound/core
AgeCommit message (Collapse)Author
32 hoursMerge branch 'for-next' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/mm/linux.git # Conflicts: # arch/alpha/Kconfig # arch/arm64/mm/pageattr.c # arch/um/Kconfig # fs/coredump.c # fs/xfs/libxfs/xfs_btree.c
4 daysALSA: pcm: use vm_insert_page() to map PCM status pageLorenzo Stoakes (ARM)
There's no need to keep a fault handler around for this, instead map on mmap. While we're here, rename area to vma to be consistent. This correctly makes the mapping a mixed map mapping. This works towards establishing the invariant that only PFN mapped or mixed map mappings may clear the VM_MAYWRITE flag. The status page mapping clears VM_MAYWRITE, so it must not be mm-managed; the control page mapping remains writable and is left fault-based. The assumption is made that the struct pcm_mmap_status structure is at most a page in size, which is asserted as a build bug. This is safe to assume, as the size of the structure is 56 bytes at most. Link: https://lore.kernel.org/20261013-b4-mmap-prepare-vma-flag-sanify-v6-13-1aa3c9b139f9@kernel.org Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Acked-by: Takashi Iwai <tiwai@suse.de> Reviewed-by: Suren Baghdasaryan <surenb@google.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Jann Horn <jannh@google.com> Cc: Pedro Falcato <pfalcato@suse.de> Cc: David Hildenbrand <david@kernel.org> Cc: Mike Rapoport <rppt@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Leon Romanovsky <leon@kernel.org> Cc: Paul Moore <paul@paul-moore.com> Cc: Stephen Smalley <stephen.smalley.work@gmail.com> Cc: Jaroslav Kysela <perex@perex.cz> Cc: Takashi Iwai <tiwai@suse.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Andrii Nakryiko <andrii@kernel.org> Cc: Eduard Zingerman <eddyz87@gmail.com> Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com> Cc: Zi Yan <ziy@nvidia.com> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Nico Pache <nico.pache@linux.dev> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Dev Jain <dev.jain@arm.com> Cc: Barry Song <baohua@kernel.org> Cc: Lance Yang <lance.yang@linux.dev> Cc: Usama Arif <usama.arif@linux.dev> Cc: Kiryl Shutsemau <kas@kernel.org> Cc: Doug Gilbert <dgilbert@interlog.com> Cc: James Bottomley <james.bottomley@hansenpartnership.com> Cc: Martin K. Petersen <mkp@kernel.org> Cc: Simona Vetter <simona@ffwll.ch> Cc: Helge Deller <deller@gmx.de> Cc: Sebastian Reichel <sre@kernel.org> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Peter Xu <peterx@redhat.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@kernel.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Rik van Riel <riel@surriel.com> Cc: Harry Yoo <harry@kernel.org> Cc: Juri Lelli <juri.lelli@redhat.com> Cc: Vincent Guittot <vincent.guittot@linaro.org> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Maxime Ripard <mripard@kernel.org> Cc: Thomas Zimmermann <tzimmermann@suse.de> Cc: David Airlie <airlied@gmail.com> Cc: Will Deacon <will@kernel.org> Cc: Aneesh Kumar K.V <aneesh.kumar@kernel.org> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Muchun Song <muchun.song@linux.dev> Cc: Oscar Salvador <osalvador@suse.de> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Jan Kara <jack@suse.cz> Cc: Marc Zyngier <maz@kernel.org> Cc: Oliver Upton <oupton@kernel.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Anup Patel <anup@brainfault.org> Cc: Paul Walmsley <pjw@kernel.org> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Christian Borntraeger <borntraeger@linux.ibm.com> Cc: Janosch Frank <frankja@linux.ibm.com> Cc: Claudio Imbrenda <imbrenda@linux.ibm.com> Cc: Alexander Gordeev <agordeev@linux.ibm.com> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: David S. Miller <davem@davemloft.net> Cc: Andreas Larsson <andreas@gaisler.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christian Brauner <brauner@kernel.org> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Joshua Hahn <joshua.hahnjy@gmail.com> Cc: Rakie Kim <rakie.kim@sk.com> Cc: Byungchul Park <byungchul@sk.com> Cc: Gregory Price <gourry@gourry.net> Cc: Ying Huang <ying.huang@linux.alibaba.com> Cc: Alistair Popple <apopple@nvidia.com> Cc: Chris Li <chrisl@kernel.org> Cc: Kairui Song <kasong@tencent.com> Cc: Kemeng Shi <shikemeng@huaweicloud.com> Cc: Nhat Pham <nphamcs@gmail.com> Cc: Baoquan He <baoquan.he@linux.dev> Cc: Youngjun Park <youngjun.park@lge.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Qi Zheng <qi.zheng@linux.dev> Cc: Shakeel Butt <shakeel.butt@linux.dev> Cc: Axel Rasmussen <axelrasmussen@google.com> Cc: Yuanchu Xie <yuanchu@google.com> Cc: Wei Xu <weixugc@google.com> Cc: Chengming Zhou <chengming.zhou@linux.dev> Cc: Michal Hocko <mhocko@kernel.org> Cc: Miklos Szeredi <miklos@szeredi.hu> Cc: Xu Xin <xu.xin@linux.dev> Cc: Ihor Solodrai <ihor.solodrai@linux.dev> Cc: Bert Karwatzki <spasswolf@web.de>
5 daysALSA: compress: reject restarting an ACTIVE task via origin_seqnoPeter Ujfalusi
snd_compr_task_start_prepare() only rejects tasks with state >= SND_COMPRESS_TASK_STATE_FINISHED. Since the enum is IDLE(0) < ACTIVE(1) < FINISHED(2), this accepts ACTIVE tasks and rejects FINISHED ones, the opposite of what the origin_seqno mechanism needs: origin_seqno is meant to let a caller reuse a FINISHED task's buffers for a new job, not to restart a task that is still queued with the driver. The seqno lookup path in snd_compr_task_start() has its own explicit "task->state != IDLE" guard, but the origin_seqno lookup path relies solely on this function, so it can restart an ACTIVE task, causing ops->task_start() to be called twice for the same task and runtime->active_tasks to be incremented twice without a matching finish/stop. Accept IDLE and FINISHED, reject ACTIVE, on both entry paths. Fixes: 04177158cf98 ("ALSA: compress_offload: introduce accel operation mode") Cc: stable@vger.kernel.org Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Acked-by: Vinod Koul <vkoul@kernel.org> Link: https://patch.msgid.link/20261019144533.30665-5-peter.ujfalusi@linux.intel.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
5 daysALSA: compress: add missing OPEN-state gate to SET_METADATAPeter Ujfalusi
snd_compr_set_metadata() calls stream->ops->set_metadata() straight after copy_from_user(), without ever checking runtime->state, even though the function's own comment says a parameter change should only be allowed once the stream has left the OPEN state. Every other metadata/param entry point in this file (SET_PARAMS, WRITE, ...) enforces that gate. A codec driver's set_metadata callback can assume SET_PARAMS has already run and initialised its private state; calling it while the stream is still OPEN can operate on that uninitialised state. Add the OPEN-state check the existing comment already documents. Fixes: 9727b490e543 ("ALSA: compress: add support for gapless playback") Cc: stable@vger.kernel.org Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Acked-by: Vinod Koul <vkoul@kernel.org> Link: https://patch.msgid.link/20261019144533.30665-4-peter.ujfalusi@linux.intel.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
5 daysALSA: compress: reject buffer geometry change on gapless next_trackPeter Ujfalusi
snd_compr_set_params() is invoked from the gapless next_track re-entry path, which calls snd_compr_allocate_buffer() again and lets buffer_size change while total_bytes_available and total_bytes_transferred still hold values computed for the previous buffer. snd_compr_calc_avail() then derives an avail/count value from those stale counters against the new buffer_size, and snd_compr_write_data() copy_from_user()s that many bytes into the new, potentially smaller buffer, overflowing it with user-controlled length and content. The buffer is set up once, with the initial SET_PARAMS, and neither the core nor the DSP expects it to change for a gapless track transition. Do not call snd_compr_allocate_buffer() on the next_track path and reject a request that changes the buffer geometry, so that the codec parameters that the driver receives match the buffer in use. Fixes: 9727b490e543 ("ALSA: compress: add support for gapless playback") Cc: stable@vger.kernel.org Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://patch.msgid.link/20261019144533.30665-3-peter.ujfalusi@linux.intel.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
5 daysALSA: compress: fix buffer leak on failed SET_PARAMSPeter Ujfalusi
When the driver has neither ops->copy nor a preallocated dma_buffer_p, snd_compr_allocate_buffer() kmallocs runtime->buffer. If ops->set_params() then rejects the parameters, SET_PARAMS fails, the stream stays in the OPEN state and keeps the buffer. The next SET_PARAMS allocates a new buffer and overwrites the pointer, so repeated SET_PARAMS calls with parameters that the driver rejects leak one buffer per call. Release the framework-owned buffer when ops->set_params() fails on an OPEN stream, so that a failed SET_PARAMS leaves no buffer behind and the buffer is allocated only once per successful setup. Use the same ownership check as snd_compr_free(). Fixes: b21c60a4edd2 ("ALSA: core: add support for compress_offload") Cc: stable@vger.kernel.org Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://patch.msgid.link/20261019144533.30665-2-peter.ujfalusi@linux.intel.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
5 daysMerge tag 'asoc-v7.4' of ↵Takashi Iwai
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus ASoC: Updates for v7.4 There's an awful lot of cleanup work in this pull request, lots from Bui Duc Phuc, Pengpeng Hou, HyeongJun An and Chancel Liu cleaning up detail issues in drivers in addition to Mormoto-san's ongoing framework work. This time Morimoto-san's work included enabling auto_selectable_formats so there's less manual configuration required for DAI links. There's also been a huge amount of upstreaming activity from Qualcomm, some pain there but hopefully enough has now landed for things to be smoother in future. - Use auto_selectable_formats in most drivers to reduce the amount of manual configuration required for DAI links. - Support for compressed audio on SOF IPC4 systems. - Support for AMD ACP 7.B and 7.F, AmLogic A9 and T7, Airoha AN7581, ESS Technology ES9039Q2M, Intel Cherry Trail with RT5688, Nuvoton NAU83G60, nVidia systems with WM8994, Qualcomm QAIF, Senary I2S, WCD9378 and various platforms, Realtek RT766 and RT767, Senary SN624x I also mistakenly merged some SPI changes in here then applied more patches on top before I noticed (it looks like this was b4's base selection logic picking a bad base for some ASoC work), highlights there are: - Improvements for spidev_test to cover additional use cases, plus be a bit easier to use. - Push more Tegra210 QSPI handling into interrupt context for performance improvements. - Support for Qualcomm QPIC SNAND v2 and RealTek RTD1625 NOR. - Documentation clarifications. - Fixes for some runtime PM and error handling issues. - Support for R-Car Gen5. (this should also be going in via my SPI pull request)
5 daysALSA: pcm: Protect channel-map reads against runtime detachCen Zhang
Channel-map controls remain accessible between PCM opens. In-tree HDA code publishes the generic controls through add_std_chmaps(), so a SNDRV_CTL_IOCTL_ELEM_READ can overlap the final close of the same PCM substream. pcm_chmap_ctl_get() checks substream->runtime and later reads its channel count. Final close clears and frees that runtime under pcm->open_mutex, while the control callback holds only controls_rwsem: Control GET Final PCM close ----------- --------------- snd_ctl_elem_read() down_read(controls_rwsem) pcm_chmap_ctl_get() check substream->runtime lock(pcm->open_mutex) snd_pcm_release_substream() snd_pcm_detach_substream() substream->runtime = NULL kfree(runtime) unlock(pcm->open_mutex) substream->runtime->channels NULL or freed-pointer access up_read(controls_rwsem) Reloading the cleared field can fault through NULL, while retaining the old pointer can access freed storage. controls_rwsem keeps the control alive, but does not serialize the matching PCM close. Copy the channel count under open_mutex and use that scalar for the map lookup. Use trylock with -EBUSY because snd_pcm_dev_disconnect() takes open_mutex before removing controls under controls_rwsem; blocking in the reverse order from GET could deadlock. Fixes: 2d3391ec0ecc ("ALSA: PCM: channel mapping API implementation") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-0b5d6bc7124d0b921f2c-v4-b9738bdeab8823999181@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
5 daysALSA: jack: Pin the module while debugfs files are openCen Zhang
With CONFIG_SND=m and CONFIG_SND_JACK_INJECTION_DEBUG enabled, an in-tree HDA jack creates these debugfs files through snd_jack_new() and snd_jack_add_debugfs(). Their file_operations live in snd, but none sets .owner. full_proxy_open_regular() therefore takes no snd module reference when it calls fops_get(real_fops). A debugfs descriptor can outlive removal of its HDA card. Once the card and dependent modules, including the OSS emulation modules, have been removed, snd can be unloaded while that descriptor is still open: Descriptor holder Card/module teardown ----------------- -------------------- open jack debugfs file full_proxy_open_regular() fops_get(real_fops) owner == NULL: no snd pin keep descriptor open remove HDA card snd_card_disconnect() snd_jack_dev_disconnect() remove debugfs nodes snd_jack_dev_free() unload dependent modules rmmod snd alsa_sound_exit() free_module(): unmap snd close descriptor full_proxy_release() read real_fops->release fops_put(real_fops) read real_fops->owner debugfs_remove() drains active operations, but does not wait for idle open descriptors. Release deliberately bypasses removal protection and reads the real table even when no release callback is installed. The last close can therefore access unloaded snd storage. Set .owner to THIS_MODULE in all six tables. The existing proxy fops_get()/fops_put() pair then keeps snd loaded through the final table access on close. Fixes: 2d670ea2bd53 ("ALSA: jack: implement software jack injection via debugfs") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-431ddb947e1a13b95d3a-v3-02d37dd7b4eb4774e100@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
5 daysALSA: pcm: Remove channel-map controls before freeing substreamsCen Zhang
A late HDA codec bind on an already registered card builds new PCMs before registering them. add_std_chmaps() publishes generic channel-map controls during this BUILD stage. If an earlier chmap succeeds and a later allocation fails, probe cleanup frees the BUILD PCM while the card's control device remains accessible. These generic controls are added directly by snd_pcm_add_chmap_ctls(); snd_hda_ctls_clear() only removes codec-tracked mixer controls. BUILD devices also skip dev_disconnect. snd_pcm_free_stream() then frees the substreams before free_chmap() withdraws their generic control: Late HDA codec bind / rollback Control GET on the live card ------------------------------ ---------------------------- hda_codec_driver_probe() snd_hda_codec_build_pcms() PCM is BUILD snd_hda_codec_build_controls() add_std_chmaps() publish an earlier chmap later allocation: -ENOMEM snd_hda_codec_cleanup_for_unbind() snd_hda_ctls_clear() generic chmap remains codec_release_pcms() snd_device_free() BUILD: skip dev_disconnect snd_pcm_free_stream() kfree(substream) snd_ctl_elem_read() down_read(controls_rwsem) pcm_chmap_ctl_get() walk freed substream free_chmap() snd_ctl_remove() wait for GET up_read(controls_rwsem) The control read lock cannot protect a substream already freed before control removal starts. The failure above occurs before snd_card_register(), so the PCM has not transitioned out of BUILD. Move free_chmap() before the substream free loop. Its snd_ctl_remove() withdraws the control and drains readers under controls_rwsem before any substream is released. Normal registered-device disconnect already removes the control, so the later call remains harmless on that path. Fixes: 2d3391ec0ecc ("ALSA: PCM: channel mapping API implementation") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-4a207d9ef3a3597a74a4-v4-80b0113669b1a62fbbe9@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
6 daysALSA: oss: Keep emulation modules loaded until object teardownCen Zhang
OSS proc entries and notifier callbacks can remain in use without an open OSS device file. Normal snd-pcm-oss removal can therefore delete an existing PCM's OSS proc entry while late HDA codec binding repeats snd_card_register() on the same live card: OSS PCM module unload Card registration --------------------- ----------------- snd_info_free_entry(entry) proc_remove(entry->p) clear entry->p snd_info_card_register() republish linked entry unlink and free entry The new proc node retains a pointer to freed storage. Mixer OSS removal can likewise release an adapter while a card notification still uses it. Hold a snd-pcm-oss module reference for each PCM registered with its notifier and a snd-mixer-oss reference for each card adapter. Release them at final unregister or FREE, after proc and adapter cleanup. Normal module unload can no longer initiate removal while these objects exist. Track PCM OSS registration with a separate bool registered. Unlike oss.reg, this state also covers unmapped PCMs and remains set across DISCONNECT until final unregister. BUILD-state and creation-error cleanup must not drop a reference when registration never acquired one. The PCM notifier's register_mutex serialization keeps the final put ahead of notifier removal and module teardown until dispatch has finished. For mixer OSS, serialize callback publication, dispatch and withdrawal in the core so module exit waits for callbacks, including one dropping the last reference, to return. Keep card enumeration in the OSS module, with card references released after dispatch drops the mutex. Ignore duplicate REGISTER notifications so a delayed registration cannot replace an adapter retained across DISCONNECT and leak its module pin. Partial HDA codec teardown can still remove an individual PCM while the card remains registered; its object-lifetime handling is separate. Fixes: 2471b6c80a70 ("ALSA: info: Register proc entries recursively, too") Suggested-by: Takashi Iwai <tiwai@suse.de> Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/pm-pmb-26d66390a25fec9fad6c-v6-5be251a3ac8832955a31-2@gmail.com
6 daysALSA: pcm: Protect the unregister notifier traversalCen Zhang
snd_pcm_free() traverses snd_pcm_notify_list and calls n_unregister without register_mutex, although snd_pcm_notify() takes that mutex to add and remove notifiers. PCM disconnect releases the mutex before the free callback runs, so it does not protect this later traversal. With no open OSS file, normal snd-pcm-oss removal can overlap PCM card teardown, for example when unbinding snd-dummy: PCM card teardown snd-pcm-oss unload ----------------- ------------------ snd_pcm_dev_disconnect() remove PCM under register_mutex unlock register_mutex snd_pcm_free() fetch notifier snd_pcm_notify(..., 1) unlink notifier under mutex free module storage read notifier->n_unregister invoke callback The free path can then read the notifier from released module storage or call its unloaded code. Hold register_mutex across the unregister traversal and its callbacks. Notifier removal must wait until both have finished. This also protects the traversal if a callback releases the last module reference: module exit cannot unlink its notifier until the free path releases the mutex. Drop the mutex before private_free and the remaining stream cleanup. Fixes: c461482c8072 ("[ALSA] Unregister device files at disconnection") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/pm-pmb-26d66390a25fec9fad6c-v6-5be251a3ac8832955a31-1@gmail.com
8 daysALSA: jack: Protect the index scan against control removalCen Zhang
A control found during a jack-name index scan must remain alive until snd_ctl_find_id() finishes comparing its ID and count. However, get_available_index() calls it without holding card->controls_rwsem. With CONFIG_SND_CTL_FAST_LOOKUP enabled, the lookup loads a raw control pointer from ctl_hash and dereferences it in elem_id_matches() without any lock that excludes removal. This can happen when a jack is created while a different jack owner on the same card removes an existing control with the same name and index. For example, probe and unbind of different HDA codecs can reach these paths on a shared card if their generated jack names match. The codec device locks do not serialize operations on different codecs. The unbind path can free the control during the index scan: Codec A: probe Codec B: unbind -------------- --------------- get_available_index() snd_ctl_find_id() kctl = xa_load(...) hda_codec_driver_remove() snd_hda_codec_cleanup_for_unbind() snd_hda_jack_tbl_clear() snd_device_free() __snd_device_free() snd_jack_dev_free() snd_ctl_remove() snd_ctl_remove_locked() __snd_ctl_remove() snd_ctl_free_one() kfree(kctl) elem_id_matches(kctl, ...) read freed id/count -> UAF Hold controls_rwsem for read across the index scan so removal cannot free a control until the lookup has finished using it. Release the lock when get_available_index() returns, before the caller adds the new control under the write lock. Fixes: 38ea4c3dc306 ("ALSA: control: Optimize locking for look-up") Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Assisted-by: LLM Link: https://patch.msgid.link/pm-pmb-f08c844bb1163c8d4fa1-v2-2f3c99e40f90134846ee@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
8 daysALSA: seq: oss: Skip events until fully initializedTakashi Iwai
When an OSS sequencer device is opened, it creates a sequencer port, then further initializes the internal states like a timer instance, etc. Since the sequencer port is published, an event can be already delivered, and this may hit unexpected event handling, which can eventually cause a NULL dereference (like the timer start/stop event triggered before the timer initialization). For avoiding such a race, introduce a simple guard and skips the event processing until the port is fully initialized. At releasing the device, in turn, clear this guard, so that any input events will be discarded during the teardown. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Reported-by: Sashiko <sashiko-bot@kernel.org> Cc: <stable@vger.kernel.org> Link: https://patch.msgid.link/20261016161930.482309-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
8 daysALSA: jack: Expose injection debugfs at device register phaseTakashi Iwai
Currently we add debugfs interfaces for jack injection (with CONFIG_SND_JACK_INJECTION_DEBUG) at creating jack kctls in snd_jack_kctl_add(). This means that those debugfs interfaces are already exposed to user-space at the early probe phase -- that is, it allows user-space already fiddling with it, while other components are still being initialized and hidden until snd_card_register(). Depending on the driver implementation, such behavior can be an unpleasant surprise. For aligning the device exposure behavior, move the debugfs registration at the device register phase, too. snd_jack_kctl_add() may still add the corresponding debugfs interfaces (for the dynamically added jacks, if any), but it's done only conditionally after the card has been registered. Reviewed-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20261016140653.4406-1-tiwai@suse.de
9 daysALSA: seq: oss: Ignore sync echoes without a write queueCen Zhang
The sync-echo callback needs a write queue before it can wake up a synchronizing writer. However, snd_seq_oss_open() publishes the session's port with snd_seq_oss_event_input() as its callback before allocating and assigning dp->writeq. A kernel caller using snd_seq_kernel_client_dispatch() with the OSS client ID can deliver an ECHO containing SEQ_SYNCTIMER to this port before the write queue is assigned. The helper stamps the supplied client ID into the event, so the callback's source-client check accepts it. Regular userspace events carry their own client ID and are rejected. The failing ordering is: OSS open Kernel direct dispatch -------- ---------------------- Zero-allocate dp Set dp->cseq Publish callback port Dispatch ECHO as the OSS client Look up and pin that port Enter snd_seq_oss_event_input() Pass NULL to writeq_wakeup() Allocate and assign dp->writeq Dispatch reaches the callback after port publication and before the queue assignment. OSS register_mutex serializes open and release, but direct dispatch does not take it. The port use reference keeps dp alive through the callback; it does not wait for constructor initialization. The wakeup helper therefore attempts to acquire sync_lock through a NULL queue pointer, causing a fault. Sample dp->writeq once in the SEQ_SYNCTIMER branch and ignore the echo when the queue is absent, matching the adjacent read-queue check. Pass the checked pointer to the wakeup helper so a NULL sample cannot reach the lock access. The existing port reference protects the queue's lifetime through this call, since port deletion drains callbacks before free_devinfo() frees the queue. KASAN report as below: Oops: general protection fault, probably for non-canonical address 0xdffffc000000000d: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000068-0x000000000000006f] CPU: 2 UID: 0 PID: 69 Comm: kworker/2:1 Tainted: G W 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) Tainted: [W]=WARN Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Workqueue: events pmbd_dispatch_early_sync_echo RIP: 0010:do_raw_spin_lock+0x71/0x270 Code: d0 60 81 49 8d 14 04 c7 02 f1 f1 f1 f1 c7 42 04 04 f3 f3 f3 65 48 8b 15 05 df 88 09 48 89 54 24 60 31 d2 48 89 fa 48 c1 ea 03 <0f> b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 b9 RSP: 0018:ffff88810450f878 EFLAGS: 00010013 RAX: dffffc0000000000 RBX: 0000000000000068 RCX: 0000000000000000 RDX: 000000000000000d RSI: 0000000000000000 RDI: 000000000000006c RBP: 0000000000000293 R08: 0000000000000001 R09: 0000000000000000 R10: ffffffff8940fe57 R11: 0000000000000000 R12: 1ffff110208a1f10 R13: 0000000000000068 R14: 0000000000000001 R15: ffff88810450fbee FS: 0000000000000000(0000) GS:ffff8881fd885000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000006d2890 CR3: 0000000106cbf002 CR4: 0000000000770ef0 PKRU: 55555554 Call Trace: <TASK> ? pmbd_probe_hit_cookie+0xee/0x1c0 ? __pfx_do_raw_spin_lock+0x10/0x10 ? lock_acquire+0x2b8/0x2f0 ? __pfx_pmbd_probe_hit_cookie+0x10/0x10 _raw_spin_lock_irqsave+0x44/0x60 ? snd_seq_oss_writeq_wakeup+0x30/0xf0 snd_seq_oss_writeq_wakeup+0x30/0xf0 snd_seq_oss_event_input+0x1e4/0x2a0 ? do_raw_read_unlock+0x49/0xe0 ? __pfx_snd_seq_oss_event_input+0x10/0x10 __snd_seq_deliver_single_event+0x105/0x1a0 ? snd_seq_port_use_ptr+0x111/0x170 snd_seq_deliver_single_event+0x2fc/0x770 ? __pfx_snd_seq_deliver_single_event+0x10/0x10 ? __pfx_pmbd_hold_maybe+0x10/0x10 snd_seq_deliver_event+0x45a/0x760 ? __pfx_do_raw_spin_lock+0x10/0x10 ? lock_acquire+0x2b8/0x2f0 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_snd_seq_deliver_event+0x10/0x10 ? _raw_spin_unlock_irqrestore+0x44/0x60 ? srso_alias_return_thunk+0x5/0xfbef5 ? trace_hardirqs_on+0x18/0x160 ? srso_alias_return_thunk+0x5/0xfbef5 ? _raw_spin_unlock_irqrestore+0x44/0x60 ? srso_alias_return_thunk+0x5/0xfbef5 snd_seq_kernel_client_dispatch+0x19c/0x1e0 pmbd_dispatch_early_sync_echo+0x121/0x1c0 ? __pfx_pmbd_dispatch_early_sync_echo+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? finish_task_switch.isra.0+0x1dc/0x980 process_one_work+0x908/0x19c0 ? __pfx_process_one_work+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 worker_thread+0x65c/0xe40 ? srso_alias_return_thunk+0x5/0xfbef5 ? __kthread_parkme+0x175/0x220 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_worker_thread+0x10/0x10 kthread+0x34f/0x460 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x659/0x940 ? __pfx_ret_from_fork+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __switch_to+0x74f/0xf80 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:do_raw_spin_lock+0x71/0x270 Code: d0 60 81 49 8d 14 04 c7 02 f1 f1 f1 f1 c7 42 04 04 f3 f3 f3 65 48 8b 15 05 df 88 09 48 89 54 24 60 31 d2 48 89 fa 48 c1 ea 03 <0f> b6 14 02 48 89 f8 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 b9 RSP: 0018:ffff88810450f878 EFLAGS: 00010013 RAX: dffffc0000000000 RBX: 0000000000000068 RCX: 0000000000000000 RDX: 000000000000000d RSI: 0000000000000000 RDI: 000000000000006c RBP: 0000000000000293 R08: 0000000000000001 R09: 0000000000000000 R10: ffffffff8940fe57 R11: 0000000000000000 R12: 1ffff110208a1f10 R13: 0000000000000068 R14: 0000000000000001 R15: ffff88810450fbee FS: 0000000000000000(0000) GS:ffff8881fd885000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000006d2890 CR3: 0000000106cbf002 CR4: 0000000000770ef0 PKRU: 55555554 Kernel panic - not syncing: Fatal exception Kernel Offset: disabled Rebooting in 1 seconds.. Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-3634251be738461947da-v2-64371e8c8d6cbf6956a3@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
9 daysALSA: vmaster: Protect follower lookup and setupCen Zhang
A control selected by snd_ctl_add_followers() must remain alive until _snd_ctl_add_follower() has copied it and installed its wrapper. The lookup returns a raw pointer without retaining the control, and neither the short-lived list lookup lock nor the fast lookup protects later use. If a kernel client adds followers to a live virtual master while another client removes or replaces a published follower, the following order is possible, with the card and master kept alive: Follower setup Control removal snd_ctl_add_followers() snd_ctl_find_id_mixer() return follower snd_ctl_remove() down_write(controls_rwsem) __snd_ctl_remove() unlink follower snd_ctl_free_one(follower) up_write(controls_rwsem) _snd_ctl_add_follower() read follower->count Removal completes after lookup returns and before setup reads the control. Since setup holds neither controls_rwsem nor a reference, the count read and subsequent control copies can access freed memory. Hold controls_rwsem for writing across the lookup and follower setup. This prevents removal or replacement from freeing the selected control until wrapper installation is complete. Write ownership also excludes control callbacks while setup changes the callback and private fields. KASAN report as below: BUG: KASAN: slab-use-after-free in _snd_ctl_add_follower+0x452/0x520 Read of size 4 at addr ffff888107957d50 by task loadmodule/491 CPU: 3 UID: 0 PID: 491 Comm: loadmodule Tainted: G O 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) Tainted: [O]=OOT_MODULE Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? _snd_ctl_add_follower+0x452/0x520 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? _snd_ctl_add_follower+0x452/0x520 kasan_report+0xe0/0x110 ? _snd_ctl_add_follower+0x452/0x520 _snd_ctl_add_follower+0x452/0x520 snd_ctl_add_followers+0x153/0x2b0 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_snd_ctl_add_followers+0x10/0x10 ? __might_fault+0x135/0x190 ? srso_alias_return_thunk+0x5/0xfbef5 ? __might_fault+0x14e/0x190 ? __pfx_fixture_write+0x10/0x10 [pmbd_vmaster_fixture] fixture_write+0x174/0x1f0 [pmbd_vmaster_fixture] ? __pfx_fixture_write+0x10/0x10 [pmbd_vmaster_fixture] ? __pfx___might_resched+0x10/0x10 proc_reg_write+0x1fb/0x2d0 vfs_write+0x25a/0x1010 ? __pfx_proc_reg_write+0x10/0x10 ? kmem_cache_free+0x242/0x580 ? __pfx_vfs_write+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? putname+0x93/0xe0 ? srso_alias_return_thunk+0x5/0xfbef5 ? do_sys_openat2+0x12a/0x1b0 ? __pfx_do_sys_openat2+0x10/0x10 ksys_write+0x111/0x200 ? __pfx_ksys_write+0x10/0x10 ? irqentry_exit+0xbe/0x820 ? srso_alias_return_thunk+0x5/0xfbef5 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f0b835a9687 Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff RSP: 002b:00007ffc82ea0360 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00007f0b83517780 RCX: 00007f0b835a9687 RDX: 0000000000000005 RSI: 0000564f8a21d074 RDI: 0000000000000003 RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000000 R13: 00007ffc82ea04f0 R14: 00007f0b83755000 R15: 0000564f8a21ed78 </TASK> Allocated by task 485: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_noprof+0x2d7/0x770 snd_ctl_new+0x51/0x190 snd_ctl_new1+0x13c/0x650 0xffffffffc04011b5 do_one_initcall+0xf3/0x4e0 do_init_module+0x281/0x8e0 load_module+0x658c/0x7cc0 init_module_from_file+0x15b/0x180 idempotent_init_module+0x22d/0x770 __x64_sys_finit_module+0xd2/0x160 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 492: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 __snd_ctl_remove+0x2ac/0x3d0 snd_ctl_remove+0x46/0x70 fixture_write+0x1ae/0x1f0 [pmbd_vmaster_fixture] proc_reg_write+0x1fb/0x2d0 vfs_write+0x25a/0x1010 ksys_write+0x111/0x200 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f The buggy address belongs to the object at ffff888107957d00 which belongs to the cache kmalloc-192 of size 192 The buggy address is located 80 bytes inside of freed 192-byte region [ffff888107957d00, ffff888107957dc0) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x107957 flags: 0x200000000000000(node=0|zone=2) page_type: f5(slab) raw: 0200000000000000 ffff8881000423c0 dead000000000100 dead000000000122 raw: 0000000000000000 0000000000100010 00000000f5000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff888107957c00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888107957c80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc >ffff888107957d00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff888107957d80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff888107957e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ================================================================== Fixes: ae07eb9bf23e ("ALSA: vmaster: Add snd_ctl_add_followers() helper") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-6c0b7e841529ddd0b21a-v2-b53dbcd593a7a4bd9582@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
9 daysALSA: pcm: refresh linked pointers before drainingJoonho Lee
Capture hardware can produce samples after the last PCM pointer update. Drain must refresh those pointers before stopping capture, or its final availability check can miss the remaining frames. With linked hardware, the first STOP may freeze other members, so refresh all running members before entering the drain action. Factor the traversal into snd_pcm_update_linked_hw_ptr(). Hold snd_pcm_link_rwsem for reading to keep membership stable during that traversal, and take each member's stream lock for its ordinary snd_pcm_update_hw_ptr() call. Include running playback streams and invoke the helper after pause resume so paused capture also receives its final update. Keep pause and drain-init outside the helper's rwsem scope. Updating a pointer inside the group drain action can enter the XRUN stop path and recursively acquire the group lock. The helper runs before that action, so an update error follows the existing group XRUN path and is returned to the caller before drain-init. Suggested-by: Takashi Iwai <tiwai@suse.de> Link: https://lore.kernel.org/all/87jynkcn60.wl-tiwai@suse.de/ Assisted-by: LLM Signed-off-by: Joonho Lee <mynameisjune111@gmail.com> Link: https://patch.msgid.link/v5-core-capture-drain-2.e9b40d3bc08c4162@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
9 daysALSA: pcm: allow capture reads while drainingJoonho Lee
Capture drain can leave buffered samples in DRAINING, but the transfer state check rejects reads in that state. Allow capture reads to consume the remaining frames while preserving the playback state check. When drain wakes a blocked capture reader, return the actual available frame count from wait_for_avail(). A zero count would make the transfer loop discard a nonempty tail. Finish capture EOF with snd_pcm_drain_done() so the state transition applies to that substream and leaves a linked playback stream draining its queued data. Allow capture hwsync to use the cached final pointer in DRAINING. Capture has already stopped, so DELAY and SYNC_PTR(HWSYNC) can report its remaining frames without another driver pointer callback. Playback retains its existing pointer update. Synthetic atomic and nonatomic tests reproduce dropped tail frames, linked playback stopping at capture EOF, and rejected position queries. With this change, a blocked read gets all 64 tail frames, playback stays DRAINING at capture EOF, and the queries succeed with no extra callback. Assisted-by: LLM Signed-off-by: Joonho Lee <mynameisjune111@gmail.com> Link: https://patch.msgid.link/v5-core-capture-drain-1.e9b40d3bc08c4162@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
9 daysALSA: mixer: oss: Serialize initial slot constructionCen Zhang
OSS mixer slot callbacks require an initialized private_data payload. However, snd_mixer_oss_notify_handler() publishes card->mixer_oss before snd_mixer_oss_build() constructs the default bindings, and snd_mixer_oss_build_input() stores get_volume before private_data. With OSS mixer emulation enabled and a native control matching a default mapping, a volume read can arrive during initial binding construction. For example, the dummy card provides the Master Volume control before registration. The following ordering lets the read use the callback before its payload is attached: Card registration OSS volume read ----------------- --------------- register the OSS mixer device publish card->mixer_oss store slot->get_volume open the mixer device lock reg_mutex invoke slot->get_volume load NULL private_data read slot->present store slot->private_data The read holds reg_mutex, but the initial builder does not acquire it. The controls_rwsem read lock protects native controls and does not serialize the builder with another reader. As a result, snd_mixer_oss_get_volume1() can dereference a NULL payload and Oops. Hold the existing reg_mutex throughout snd_mixer_oss_build(), as proc remapping already does for snd_mixer_oss_build_input(). A request can no longer invoke a callback between its installation and the payload store. This keeps the existing reg_mutex-before-controls_rwsem lock order. KASAN report as below: Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 1 UID: 0 PID: 431 Comm: alsa-oss-trigge Tainted: G O 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) Tainted: [O]=OOT_MODULE Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:snd_mixer_oss_get_volume1+0xd1/0x610 [snd_mixer_oss] Code: 00 c7 03 64 00 00 00 e9 b8 01 00 00 e8 e8 82 44 c1 49 8d 75 04 48 b8 00 00 00 00 00 fc ff df 48 89 f2 48 89 34 24 48 c1 ea 03 <0f> b6 14 02 48 89 f0 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 3f RSP: 0018:ffff888104c67cc8 EFLAGS: 00010257 RAX: dffffc0000000000 RBX: ffff888104c67d80 RCX: ffffffffc0406cb8 RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffffffff862d93a4 RBP: ffff888104c67d90 R08: 0000000000000001 R09: 0000000000000001 R10: ffffffff89406e57 R11: ffff888104c9d700 R12: ffff888113c48038 R13: 0000000000000000 R14: ffff888113c48000 R15: ffff888104646820 FS: 00007f7904d29780(0000) GS:ffff8881fd81d000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f7904e388e0 CR3: 000000010662c002 CR4: 0000000000770ef0 PKRU: 55555554 Call Trace: <TASK> snd_mixer_oss_ioctl1+0x25d/0x16f0 [snd_mixer_oss] ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_snd_mixer_oss_get_volume1+0x10/0x10 [snd_mixer_oss] ? __pfx_snd_mixer_oss_ioctl1+0x10/0x10 [snd_mixer_oss] ? lock_release+0xc8/0x280 ? pmbd_site_is_armed+0xa1/0xd0 ? lockdep_hardirqs_on_prepare+0xea/0x1a0 ? trace_hardirqs_on+0x18/0x160 ? srso_alias_return_thunk+0x5/0xfbef5 ? _raw_spin_unlock_irqrestore+0x44/0x60 ? srso_alias_return_thunk+0x5/0xfbef5 ? pmbd_gate_site_armed+0x31/0x1c0 ? srso_alias_return_thunk+0x5/0xfbef5 ? pmbd_probe_hit_cookie+0xee/0x1c0 ? __pfx_pmbd_probe_hit_cookie+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? selinux_file_ioctl+0xaa/0x280 snd_mixer_oss_ioctl+0x4a/0x80 [snd_mixer_oss] ? __pfx_snd_mixer_oss_ioctl+0x10/0x10 [snd_mixer_oss] __x64_sys_ioctl+0x163/0x1d0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f7904e3891b Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 1c 48 8b 44 24 18 64 48 2b 04 25 28 00 00 RSP: 002b:00007ffc72071e20 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7904e3891b RDX: 00007ffc72071e84 RSI: 0000000080044d00 RDI: 0000000000000003 RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffc72072e12 R13: 00007ffc72072060 R14: 00007f7904f67000 R15: 000055cd1e601d50 </TASK> Modules linked in: snd_dummy(O) snd_mixer_oss(O) ---[ end trace 0000000000000000 ]--- RIP: 0010:snd_mixer_oss_get_volume1+0xd1/0x610 [snd_mixer_oss] Code: 00 c7 03 64 00 00 00 e9 b8 01 00 00 e8 e8 82 44 c1 49 8d 75 04 48 b8 00 00 00 00 00 fc ff df 48 89 f2 48 89 34 24 48 c1 ea 03 <0f> b6 14 02 48 89 f0 83 e0 07 83 c0 03 38 d0 7c 08 84 d2 0f 85 3f RSP: 0018:ffff888104c67cc8 EFLAGS: 00010257 RAX: dffffc0000000000 RBX: ffff888104c67d80 RCX: ffffffffc0406cb8 RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffffffff862d93a4 RBP: ffff888104c67d90 R08: 0000000000000001 R09: 0000000000000001 R10: ffffffff89406e57 R11: ffff888104c9d700 R12: ffff888113c48038 R13: 0000000000000000 R14: ffff888113c48000 R15: ffff888104646820 FS: 00007f7904d29780(0000) GS:ffff8881fd81d000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f7904e388e0 CR3: 000000010662c002 CR4: 0000000000770ef0 PKRU: 55555554 Kernel panic - not syncing: Fatal exception Kernel Offset: disabled Rebooting in 1 seconds.. Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-99c1214968ae9fa4d744-v2-df0befb9a699eb50dcec@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
9 daysALSA: pcm: Call snd_pcm_sync_stop outside spinlock in snd_pcm_drop()Takashi Iwai
In the recent addition of snd_pcm_sync_stop() call at snd_pcm_drop(), I overlooked the guard() line in snd_pcm_drop() (and the review overlooked, too) -- it must be called outside, of course! Let's fix it. Now guard() became scoped_guard(), and its range is shown more clearly. Fixes: fdf9a21cda78 ("ALSA: pcm: Apply sync-stop at SNDRV_PCM_IOCTL_DROP ioctl") Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Closes: https://lore.kernel.org/c2bc1478-5999-455f-bd67-8b536c452215@samsung.com Link: https://patch.msgid.link/20261015190147.230736-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
9 daysALSA: core: Serialize snd_refcount put and syncTakashi Iwai
When a thread tries to sync-and-destroy the resource with snd_refcount_sync(), it might lead to a UAF in a very slight time window. Namely, snd_refount_put() calls wake_up() after atomic_dec_and_test(), but wait_event() in snd_refcount_sync() checks the condition via atomic_test() without serialization, hence the thread that called snd_refcount_sync() can continue immediately to release the resource before another thread calls wake_up(). For avoiding the race above, introduce the spinlock and take it at snd_refcount_put() and snd_refcount_sync() in order to serialize the operations. Fixes: dcca9b6064c3 ("ALSA: Add simple refcount helper functions") Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20261015071838.31082-1-tiwai%40suse.de Reviewed-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/20261015112256.3902-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
9 daysALSA: pcm: Add refcount for races between drain and unlinkTakashi Iwai
We added a workaround for the case where a linked substream gets unlinked during the drain operation by another substream of the same linked group in the commit 9b1dbd69ba6f ("ALSA: pcm: fix use-after-free on linked stream runtime in snd_pcm_drain()"). There, we just cached the parameters of the draining substream for avoiding UAF. Then, we check the draining substream (to_check) again in the loop and remove it from the queue only when it's still present. It means, however, that the wait queue entry won't be removed if the substream went out of the link beforehand, hence a stale wq entry remains. Later on, this can be woken up, and this may hit a UAF, too. The problem surfaced more due to the recent change to call snd_pcm_unlink() earlier. For properly handling both cases above, in this patch, we introduce a refcount to the snd_pcm_runtime that indicates the substream is being accessed / used, then at snd_pcm_release_substream(), it's synced before the actual resource release via snd_refcount_sync(). This guarantees that the accessors are finished, and safe to release memories. Along with the introduction of a refcount, the comments and the code changes by the former fix were partially reverted as they don't fit with the updated code flow any longer. Last but not least, the setup of wait queue entry and prepare_to_wait() call are moved before the group unref. With this change, we can avoid the race between the enqueue and the wakeup, too. Fixes: 9b1dbd69ba6f ("ALSA: pcm: fix use-after-free on linked stream runtime in snd_pcm_drain()") Link: https://patch.msgid.link/20261015071838.31082-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
9 daysALSA: ump: Correct return size of fill_rpn()Takashi Iwai
The RPN/NRPN conversion in fill_rpn() is supposed to return the number of bytes of the resultant UMP packet, but it returns boolean values. This would result in the incorrect ump_bytes in the converter, which will confuse stream processing. Correct to the right value 8 as a MIDI 2.0 UMP packet. Fixes: e6ce8a28c768 ("ALSA: ump: Transmit RPN/NRPN message at each MSB/LSB data reception") Cc: <stable@vger.kernel.org> Link: https://patch.msgid.link/20261015075439.50088-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
10 daysALSA: pcm: Apply sync-stop at SNDRV_PCM_IOCTL_DROP ioctlTakashi Iwai
When a PCM stream is stopped via SNDRV_PCM_IOCTL_DROP ioctl, it calls snd_pcm_stop() but sync-stop operation is missing. Although this is usually no big issue, let's add snd_pcm_sync_stop() call, just to be sure. Link: https://patch.msgid.link/20261014142454.320703-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
10 daysALSA: pcm: Serialize and check HW_REFINE ioctlsCen Zhang
Hardware refinement must reject disconnected streams before entering their runtime constraint rules. The native ioctl checks the state at the outer dispatch, before copying the parameters, while the compat HW_REFINE32 path only checks that the runtime exists. Both call the unlocked refinement helper without the buffer access lock used by HW_PARAMS. The BUFFER_BYTES rule keeps a substream pointer as its private payload. A compat request can still enter that rule after component disconnect. If component free overlaps its execution, the following order permits a use-after-free read of buffer_bytes_max: Component cleanup Compat HW_REFINE ----------------- ---------------- snd_pcm_dev_disconnect() Runtime -> DISCONNECTED Enter compat ioctl snd_pcm_hw_refine() Enter BUFFER_BYTES rule snd_device_free() snd_pcm_free_stream() Free substream Read buffer_bytes_max Add a wrapper that acquires the existing buffer access lock and checks the same allowed states and mmap conditions as HW_PARAMS before running the refinement rules. Share the state checker with snd_pcm_hw_params() and use the wrapper for native, compat and legacy PCM HW_REFINE ioctls. This rejects the described entry after disconnect and serializes these refinement calls with other buffer-locked parameter operations. Keep the original snd_pcm_hw_refine() helper for existing internal callers, including snd_pcm_hw_params() which already holds the buffer lock, to avoid locking that mutex recursively. KASAN report as below: BUG: KASAN: slab-use-after-free in snd_pcm_hw_rule_buffer_bytes_max+0x276/0x2a0 Read of size 8 at addr ffff888111b36870 by task pmbd_alsa_reade/486 CPU: 2 UID: 0 PID: 486 Comm: pmbd_alsa_reade Tainted: G O 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) Tainted: [O]=OOT_MODULE Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? snd_pcm_hw_rule_buffer_bytes_max+0x276/0x2a0 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? snd_pcm_hw_rule_buffer_bytes_max+0x276/0x2a0 kasan_report+0xe0/0x110 ? snd_pcm_hw_rule_buffer_bytes_max+0x276/0x2a0 snd_pcm_hw_rule_buffer_bytes_max+0x276/0x2a0 ? snd_pcm_hw_rule_div+0x16b/0x200 ? __pfx_snd_pcm_hw_rule_buffer_bytes_max+0x10/0x10 ? constrain_params_by_rules+0x17a/0xfe0 constrain_params_by_rules+0x506/0xfe0 ? __pfx_constrain_params_by_rules+0x10/0x10 ? __ia32_compat_sys_ioctl+0x289/0x2f0 ? do_int80_emulation+0x14a/0x5e0 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_release+0xc8/0x280 ? srso_alias_return_thunk+0x5/0xfbef5 ? snd_interval_refine+0x284/0x470 snd_pcm_hw_refine+0x768/0xcc0 ? __pfx_snd_pcm_hw_refine+0x10/0x10 ? _copy_from_user+0x51/0xa0 snd_pcm_ioctl_hw_params_compat+0x138/0x280 snd_pcm_ioctl_compat+0x4c5/0x7c0 ? __pfx_snd_pcm_ioctl_compat+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? selinux_file_ioctl+0xaa/0x280 ? ksys_write+0x16b/0x200 ? __pfx_snd_pcm_ioctl_compat+0x10/0x10 __ia32_compat_sys_ioctl+0x289/0x2f0 ? srso_alias_return_thunk+0x5/0xfbef5 do_int80_emulation+0x14a/0x5e0 asm_int80_emulation+0x1a/0x20 RIP: 0023:0x8049084 Code: 80 b8 04 00 00 00 bb 01 00 00 00 b9 43 a0 04 08 ba 2b 00 00 00 cd 80 b8 36 00 00 00 89 f3 b9 10 41 5c c2 ba b8 b0 04 08 cd 80 <85> c0 78 6c b8 04 00 00 00 bb 01 00 00 00 b9 27 a0 04 08 ba 1c 00 RSP: 002b:00000000ffd35e40 EFLAGS: 00000246 ORIG_RAX: 0000000000000036 RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00000000c25c4110 RDX: 000000000804b0b8 RSI: 0000000000000003 RDI: 0000000000000004 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 </TASK> Allocated by task 486: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 snd_pcm_new_stream+0x98f/0x1350 _snd_pcm_new+0x1d1/0x310 snd_pcm_new+0x43/0x60 0xffffffffc0401115 do_one_initcall+0xf3/0x4e0 do_init_module+0x281/0x8e0 load_module+0x658c/0x7cc0 init_module_from_file+0x15b/0x180 idempotent_init_module+0x22d/0x770 __x64_sys_finit_module+0xd2/0x160 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 494: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 snd_pcm_free_stream+0xcf/0x290 snd_pcm_free+0xb1/0xf0 __snd_device_free+0x1a1/0x490 snd_device_free+0xcf/0x190 case_owner_ioctl+0xb8/0x160 [pmbd_alsa_fixture] __x64_sys_ioctl+0x163/0x1d0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f The buggy address belongs to the object at ffff888111b36800 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 112 bytes inside of freed 1024-byte region [ffff888111b36800, ffff888111b36c00) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888111b35800 pfn:0x111b30 head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0x200000000000240(workingset|head|node=0|zone=2) page_type: f5(slab) raw: 0200000000000240 ffff888100042dc0 ffffea0004218610 ffffea00042c6810 raw: ffff888111b35800 000000000010000f 00000000f5000000 0000000000000000 head: 0200000000000240 ffff888100042dc0 ffffea0004218610 ffffea00042c6810 head: ffff888111b35800 000000000010000f 00000000f5000000 0000000000000000 head: 0200000000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff888111b36700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff888111b36780: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc >ffff888111b36800: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff888111b36880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888111b36900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== Suggested-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Assisted-by: LLM Link: https://patch.msgid.link/pm-pmb-b3f7b3445bb11aaa9a7b-v3-371faafc2599ec7fa136@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
10 daysALSA: pcm: Unlink substreams before releasing themCen Zhang
A closing PCM substream can remain in its linked group after the driver close callback has freed its private data. With two configured dummy capture substreams on the same PCM device, linked with LINK, PREPARE on the surviving substream can still visit the closing member: Final close of A PREPARE on linked B ---------------- ------------------- snd_pcm_drop(): group -> SETUP do_hw_free(A) dummy_pcm_close(A): free dpcm Take snd_pcm_link_rwsem for reading Walk the group, including A dummy_pcm_prepare(A) Read freed timer_ops pcm_release_private(A) snd_pcm_unlink(A) Unlink at the start of final substream release, before dropping the stream or releasing driver resources. The link write lock waits for an existing group PREPARE, and unlink removes the closing member from later group actions. Keep the existing stop synchronization in do_hw_free() before the driver resources are freed. Make unlink independent of the pcm_release callback so OSS substreams are covered too. Remove the native-only unlink callback and its registration, while retaining the callback hook for OSS cleanup. The existing KASAN report below records the freed timer_ops read in dummy_pcm_prepare(). KASAN report as below: BUG: KASAN: slab-use-after-free in dummy_pcm_prepare+0xb7/0xc0 Read of size 8 at addr ffff888106b35f00 by task alsa_pcm_fixtur/491 Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? dummy_pcm_prepare+0xb7/0xc0 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? dummy_pcm_prepare+0xb7/0xc0 kasan_report+0xe0/0x110 ? dummy_pcm_prepare+0xb7/0xc0 dummy_pcm_prepare+0xb7/0xc0 snd_pcm_do_prepare+0x71/0xb0 snd_pcm_action_group+0x505/0xb30 snd_pcm_action_nonatomic+0xab/0x150 snd_pcm_common_ioctl+0x1bf5/0x3a50 ? srso_alias_return_thunk+0x5/0xfbef5 ? do_vfs_ioctl+0x1f5/0x1280 ? __pfx_do_vfs_ioctl+0x10/0x10 ? ioctl_has_perm.constprop.0.isra.0+0x34f/0x500 ? __pfx_snd_pcm_common_ioctl+0x10/0x10 ? __fput+0x5ba/0xa60 ? srso_alias_return_thunk+0x5/0xfbef5 snd_pcm_ioctl+0x76/0xb0 ? __pfx_snd_pcm_ioctl+0x10/0x10 __x64_sys_ioctl+0x163/0x1d0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x41ee8d Code: 04 25 28 00 00 00 48 89 45 c8 31 c0 48 8d 45 10 c7 45 b0 10 00 00 00 48 89 45 b8 48 8d 45 d0 48 89 45 c0 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 1a 48 8b 45 c8 64 48 2b 04 25 28 00 00 00 RSP: 002b:00007ffcfa72fb60 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 000000000041ee8d RDX: 0000000000000000 RSI: 0000000000004140 RDI: 0000000000000004 RBP: 00007ffcfa72fbb0 R08: 00007ffcfa72fb98 R09: 0000000000000110 R10: 0000000000000001 R11: 0000000000000246 R12: 00007ffcfa72fcd8 R13: 00007ffcfa72fcf0 R14: 00000000004a8f28 R15: 0000000000000001 </TASK> Allocated by task 488: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 dummy_hrtimer_create+0x4a/0x170 dummy_pcm_open+0xe7/0x730 snd_pcm_open_substream+0x926/0x1580 snd_pcm_open+0x28d/0x6d0 snd_pcm_capture_open+0x82/0xe0 snd_open+0x1ec/0x3e0 chrdev_open+0x21f/0x660 do_dentry_open+0x5c8/0x1300 vfs_open+0x87/0x390 path_openat+0x2460/0x3cd0 do_file_open+0x21e/0x470 do_sys_openat2+0xf4/0x1b0 __x64_sys_openat+0x136/0x1e0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 490: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 dummy_hrtimer_free+0x72/0xe0 dummy_pcm_close+0x9f/0xd0 snd_pcm_release_substream.part.0+0x104/0x310 snd_pcm_release+0x106/0x240 __fput+0x39f/0xa60 fput_close_sync+0xff/0x200 __x64_sys_close+0x8c/0xf0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f ================================================================== Fixes: 1576274d3028 ("[ALSA] Fix Oops of PCM OSS emulation") Suggested-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-9c80f858ccc13b3de84d-v7-fcd8c7aa0e837bf0b036@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
11 daysALSA: seq: oss: Prevent duplicate MIDI device teardownCen Zhang
Each OSS MIDI alias and its coder must have one final-release owner. find_slot() pins the alias under register_lock, but snd_seq_oss_midi_check_exit_port() clears its slot in a separate critical section without checking whether another callback already removed it. The use counter protects active users, but draining it does not elect a single remover. This requires overlapping raw kernel-client port controls for the same client. snd_seq_kernel_client_ctl() does not take ioctl_mutex, and snd_seq_delete_port() releases ports_mutex before returning to the DELETE_PORT handler's PORT_EXIT broadcast. If the old deletion is delayed before that broadcast, a new port can reuse the vacant address. Its PORT_START finds and keeps the old alias. Deleting the replacement then produces a second PORT_EXIT for the same address. Non-atomic subscriber delivery holds a read rwsem, so the two receive_announce() callbacks can run concurrently: Old-port deletion Replacement-port controls ----------------- ------------------------- Unlink and drain old port Delay before PORT_EXIT Create port at the same address PORT_START keeps existing alias Delete port; PORT_EXIT pins mdev PORT_EXIT pins the same mdev Clear slot; drop pin Clear slot; drop pin Wait for users to drain Wait for users to drain Free coder; pause before kfree(mdev) Free coder again: read freed coder->buf Both callbacks can select the same alias before either clears its slot. After both drop their pins, both waits can return. The second call to snd_midi_event_free() can then read the freed coder's buffer pointer, as in the report below, and attempt to release the same objects twice. Check that the pinned alias still occupies its slot under register_lock before clearing it. A callback that finds it already removed drops its pin and returns. Only the callback that removes the alias drains users and frees the coder and record. The pin keeps the record alive through this check, and the wait remains outside the spinlock. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in snd_midi_event_free+0x53/0x60 Read of size 8 at addr ffff888107074518 by task alsa-seq-fixtur/492 CPU: 3 UID: 0 PID: 492 Comm: alsa-seq-fixtur Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? snd_midi_event_free+0x53/0x60 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? snd_midi_event_free+0x53/0x60 kasan_report+0xe0/0x110 ? snd_midi_event_free+0x53/0x60 snd_midi_event_free+0x53/0x60 snd_seq_oss_midi_check_exit_port+0x1d8/0x370 receive_announce+0x1b8/0x370 ? __pfx_receive_announce+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __lock_acquire+0x466/0x2260 ? snd_seq_port_use_ptr+0x40/0x170 ? srso_alias_return_thunk+0x5/0xfbef5 ? find_held_lock+0x2b/0x80 ? snd_seq_port_use_ptr+0x10c/0x170 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_release+0xc8/0x280 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_receive_announce+0x10/0x10 __snd_seq_deliver_single_event+0x105/0x1a0 ? snd_seq_port_use_ptr+0x111/0x170 snd_seq_deliver_single_event+0x2fc/0x770 ? __pfx_snd_seq_deliver_single_event+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_down_read_nested+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? do_raw_read_unlock+0x49/0xe0 ? srso_alias_return_thunk+0x5/0xfbef5 ? _raw_read_unlock+0x23/0x40 snd_seq_deliver_event+0x351/0x760 ? __pfx_snd_seq_deliver_event+0x10/0x10 ? _raw_spin_unlock_irqrestore+0x44/0x60 ? trace_hardirqs_on+0x18/0x160 ? srso_alias_return_thunk+0x5/0xfbef5 ? _raw_spin_unlock_irqrestore+0x44/0x60 ? srso_alias_return_thunk+0x5/0xfbef5 snd_seq_kernel_client_dispatch+0x13f/0x170 snd_seq_system_broadcast+0x100/0x150 ? __pfx_snd_seq_system_broadcast+0x10/0x10 ? mark_held_locks+0x40/0x70 ? _raw_spin_unlock_irqrestore+0x44/0x60 ? srso_alias_return_thunk+0x5/0xfbef5 ? lockdep_hardirqs_on_prepare+0xea/0x1a0 ? srso_alias_return_thunk+0x5/0xfbef5 snd_seq_ioctl_delete_port+0x179/0x4b0 call_seq_client_ctl+0x90/0x110 snd_seq_kernel_client_ctl+0x8a/0x100 pmbd_case_delete_port+0xa6/0xf0 ? __pfx_pmbd_case_delete_port+0x10/0x10 ? __might_fault+0xdd/0x190 ? srso_alias_return_thunk+0x5/0xfbef5 ? __might_fault+0x14e/0x190 ? srso_alias_return_thunk+0x5/0xfbef5 ? strim+0x19c/0x200 pmbd_case_control_write+0x2c5/0x470 ? __pfx_pmbd_case_control_write+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __debugfs_file_get+0x1bd/0x7f0 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_acquire+0x17b/0x2f0 ? ksys_write+0x111/0x200 full_proxy_write+0x11f/0x180 vfs_write+0x25a/0x1010 ? __pfx_full_proxy_write+0x10/0x10 ? __pfx___mutex_lock+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_acquire+0x17b/0x2f0 ? __pfx_vfs_write+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? srso_alias_return_thunk+0x5/0xfbef5 ? __fget_files+0x1e1/0x370 ksys_write+0x111/0x200 ? __pfx_ksys_write+0x10/0x10 ? rseq_register.isra.0+0x1f3/0x2e0 ? srso_alias_return_thunk+0x5/0xfbef5 ? exit_to_user_mode_loop+0x3a5/0x570 ? srso_alias_return_thunk+0x5/0xfbef5 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f3532e4e9ee Code: 08 0f 85 f5 4b ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 80 00 00 00 00 48 83 ec 08 RSP: 002b:00007f3532dafe08 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00007f3532db06c0 RCX: 00007f3532e4e9ee RDX: 000000000000000a RSI: 000055efbd747156 RDI: 0000000000000003 RBP: 000055efbd747156 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 000000000000000a R13: 0000000000000000 R14: 00007ffe7894e7f0 R15: 00007f35325b0000 </TASK> Allocated by task 490: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 snd_midi_event_new+0x74/0x210 snd_seq_oss_midi_check_new_port+0x329/0x610 receive_announce+0x277/0x370 __snd_seq_deliver_single_event+0x105/0x1a0 snd_seq_deliver_single_event+0x2fc/0x770 snd_seq_deliver_event+0x351/0x760 snd_seq_kernel_client_dispatch+0x13f/0x170 snd_seq_system_broadcast+0x100/0x150 snd_seq_ioctl_create_port+0x39a/0x9d0 call_seq_client_ctl+0x90/0x110 snd_seq_kernel_client_ctl+0x8a/0x100 pmbd_case_create_port+0xcc/0x160 pmbd_case_control_write+0x21d/0x470 full_proxy_write+0x11f/0x180 vfs_write+0x25a/0x1010 ksys_write+0x111/0x200 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 493: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 snd_midi_event_free+0x48/0x60 snd_seq_oss_midi_check_exit_port+0x1d8/0x370 receive_announce+0x1b8/0x370 __snd_seq_deliver_single_event+0x105/0x1a0 snd_seq_deliver_single_event+0x2fc/0x770 snd_seq_deliver_event+0x351/0x760 snd_seq_kernel_client_dispatch+0x13f/0x170 snd_seq_system_broadcast+0x100/0x150 snd_seq_ioctl_delete_port+0x179/0x4b0 call_seq_client_ctl+0x90/0x110 snd_seq_kernel_client_ctl+0x8a/0x100 pmbd_case_delete_port+0xa6/0xf0 pmbd_case_control_write+0x398/0x470 full_proxy_write+0x11f/0x180 vfs_write+0x25a/0x1010 ksys_write+0x111/0x200 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f The buggy address belongs to the object at ffff888107074500 which belongs to the cache kmalloc-96 of size 96 The buggy address is located 24 bytes inside of freed 96-byte region [ffff888107074500, ffff888107074560) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x107074 flags: 0x200000000000000(node=0|zone=2) page_type: f5(slab) raw: 0200000000000000 ffff888100042280 dead000000000122 0000000000000000 raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff888107074400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff888107074480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc >ffff888107074500: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc ^ ffff888107074580: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc ffff888107074600: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc ================================================================== Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-7c5128efe2110a87b872-v2-c718183fd693e73d8e95@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
11 daysALSA: vmaster: Serialize hook registration with control callbacksCen Zhang
An HDA virtual-master hook must have its private argument initialized before a control callback can invoke it. snd_hda_add_vmaster_hook() installs the trampoline through snd_ctl_add_vmaster_hook(), which stores master->hook before master->hook_private_data without serialization. When a codec with a vmaster mute hook binds to an already registered card, snd_hda_gen_build_controls() publishes and initializes the Master Playback Switch before installing the hook. A native write that changes the switch can then run in the following order: 1. The codec bind path publishes and initializes the master control in __snd_hda_add_vmaster(), then calls snd_hda_add_vmaster_hook(). 2. The hook setter stores master->hook, but has not yet stored its private argument. 3. SNDRV_CTL_IOCTL_ELEM_WRITE takes controls_rwsem and calls master_put() while the setter remains between those stores. 4. master_put() sees the callback and invokes vmaster_hook() with a NULL argument. The trampoline dereferences it before the setter can complete publication. The write lock held by snd_ctl_elem_write() does not exclude the hook setter, so this can cause a NULL pointer dereference. Take the same controls_rwsem for writing inside snd_ctl_add_vmaster_hook() so the callback and its argument are installed together with respect to native control callbacks. Pass the card into the helper and update the HDA caller, keeping the lock in the ALSA core. Release it when registration returns, before the caller synchronizes the hook. KASAN report as below: Oops: general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] CPU: 1 UID: 0 PID: 499 Comm: alsa-vmaster-tr Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:vmaster_hook+0x35/0xb0 Code: f5 53 48 89 fb 48 83 ec 08 e8 57 f0 9a fc eb 50 e8 50 f0 9a fc 48 8d 7b 08 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 75 59 48 8d 7b 10 48 8b 43 08 48 ba 00 00 00 00 00 fc RSP: 0018:ffff888117647cd0 EFLAGS: 00010212 RAX: dffffc0000000000 RBX: 0000000000000000 RCX: ffffffff84e9ff50 RDX: 0000000000000001 RSI: 0000000000000000 RDI: 0000000000000008 RBP: 0000000000000001 R08: 0000000000000001 R09: 0000000000000001 R10: ffffffff89427457 R11: ffff888115ad1d00 R12: ffffffff84e9ff30 R13: ffff888114943ca0 R14: 0000000000000000 R15: 0000000000000001 FS: 00007fe8167b3780(0000) GS:ffff88826b7e3000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000557c8c2842a8 CR3: 000000011579f005 CR4: 0000000000770ef0 PKRU: 55555554 Call Trace: <TASK> master_put+0x20e/0x2b0 snd_ctl_elem_write+0x37f/0x5e0 snd_ctl_ioctl+0x997/0xdd0 ? __pfx_snd_ctl_ioctl+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? selinux_file_ioctl+0xaa/0x280 ? __pfx_snd_ctl_ioctl+0x10/0x10 __x64_sys_ioctl+0x163/0x1d0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fe8168c291b Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 1c 48 8b 44 24 18 64 48 2b 04 25 28 00 00 RSP: 002b:00007fffab0cb150 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fe8168c291b RDX: 00007fffab0cb310 RSI: 00000000c4c85513 RDI: 0000000000000003 RBP: 00007fffab0cb310 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001 R13: 00007fffab0cb1c0 R14: 0000000000000001 R15: 0000557c4f71fd10 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- Fixes: ee52e56e7b12 ("ALSA: hda - Fix mute-LED fixed mode") Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Assisted-by: LLM Link: https://patch.msgid.link/pm-pmb-c2667fb9cc42fbb7943c-v4-b7bc2fe90e950accb3f7@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
11 daysALSA: pcm: Protect delay DMA sync in forward and rewind, tooTakashi Iwai
Like the previous fix for snd_pcm_delay() (in the commit 50f413b83b31 "ALSA: pcm: Protect delay DMA sync against concurrent HW_FREE"), the snd_pcm_dma_buffer_sync() call in snd_pcm_forward() and snd_pcm_rewind() needs the similar protection against the concurrent hw_free action for avoiding potential UAFs. Fixes: a25684a95646 ("ALSA: memalloc: Support for non-contiguous page allocation") Reported-by: Sashiko <sashiko-bot@kernel.org> Link: https://patch.msgid.link/20261013120528.52586-4-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
11 daysALSA: jack: Fix kctl free at error in snd_jack_kctl_new()Takashi Iwai
When an error happens in snd_jack_kctl_new(), it tries to free the new kcontrol element via snd_ctl_free_one(). But snd_ctl_free_one() releases only the memories, and the internal linked list and hash entries still remain, which may lead to bogus accesses to user. Replace with the correct destructor, snd_ctl_remove(), for clearing the whole resources of the given kcontrol, instead. Fixes: 9058cbe1eed2 ("ALSA: jack: implement kctl creating for jack devices") Reported-by: Sashiko <sashiko-bot@kernel.org> Link: https://patch.msgid.link/20261013120528.52586-2-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
11 daysALSA: pcm: Fix driver_tstamp value reportingAmadeusz Sławiński
In some cases (system32 and compat64) due to incorrect assignment wrong value is being reported. Fix it. Fixes: 3ddee7f88aaf ("ALSA: Avoid using timespec for struct snd_pcm_status") Signed-off-by: Amadeusz Sławiński <amade@asmblr.net> Link: https://patch.msgid.link/20261013164256.4949-1-amade@asmblr.net Signed-off-by: Takashi Iwai <tiwai@suse.de>
11 daysALSA: pcm: Protect delay DMA sync against concurrent HW_FREECen Zhang
A PCM DMA buffer must remain allocated until explicit DMA synchronization finishes. snd_pcm_delay() calls snd_pcm_dma_buffer_sync() after dropping the stream lock, without participating in the buffer-access exclusion used by HW_FREE. With a managed NONCONTIG buffer requiring explicit sync, HW_PARAMS can allocate a separate runtime descriptor when the requested ring exceeds the preallocation. In PREPARED state with mmap_count zero, concurrent HWSYNC and HW_FREE calls on the same open PCM file can interleave: 1. HWSYNC checks the state in snd_pcm_delay() under the stream lock and releases that lock. 2. The sync helper fetches runtime->dma_buffer_p and enters snd_dma_noncontig_sync() with that descriptor. 3. HW_FREE takes the negative buffer-access count, checks PREPARED under the stream lock, releases the lock, and frees the DMA allocation and dynamic descriptor through snd_pcm_lib_free_pages(). 4. The sync callback resumes and reads the freed descriptor. The stream lock does not cover the allocation's release, and the sync operation has no positive buffer-access count to prevent it. The stale read causes a use-after-free in snd_dma_noncontig_sync(). DELAY uses the same snd_pcm_delay() path. Take a positive buffer-access count before checking the state and keep it until the DMA sync finishes, as the transfer and mmap paths already do. HW_FREE then returns -EBUSY while this access is active. If a buffer writer has already entered, snd_pcm_delay() returns -EBUSY before using the buffer. Keep the sync outside the stream lock and balance the count on the state-error path as well. KASAN report as below: BUG: KASAN: slab-use-after-free in snd_dma_noncontig_sync+0x295/0x310 [snd_pcm] Read of size 4 at addr ffff888108f58584 by task pcm-uaf-fixture/487 CPU: 1 UID: 0 PID: 487 Comm: pcm-uaf-fixture Not tainted 7.2.0-rc6-pmb-alsa-functional-v2+ #1 PREEMPT(lazy) Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? snd_dma_noncontig_sync+0x295/0x310 [snd_pcm] ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? snd_dma_noncontig_sync+0x295/0x310 [snd_pcm] kasan_report+0xe0/0x110 ? snd_dma_noncontig_sync+0x295/0x310 [snd_pcm] ? __pfx_snd_dma_noncontig_sync+0x10/0x10 [snd_pcm] snd_dma_noncontig_sync+0x295/0x310 [snd_pcm] ? __pfx_snd_dma_noncontig_sync+0x10/0x10 [snd_pcm] snd_dma_buffer_sync+0xc9/0x110 [snd_pcm] snd_pcm_delay+0x3bd/0x550 [snd_pcm] snd_pcm_common_ioctl+0x1e7/0x3aa0 [snd_pcm] ? srso_alias_return_thunk+0x5/0xfbef5 ? do_vfs_ioctl+0x1f5/0x1280 ? __pfx_do_vfs_ioctl+0x10/0x10 ? ioctl_has_perm.constprop.0.isra.0+0x34f/0x500 ? __pfx_snd_pcm_common_ioctl+0x10/0x10 [snd_pcm] ? srso_alias_return_thunk+0x5/0xfbef5 snd_pcm_ioctl+0x76/0xb0 [snd_pcm] ? __pfx_snd_pcm_ioctl+0x10/0x10 [snd_pcm] __x64_sys_ioctl+0x163/0x1d0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f1cae7ab91b Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 1c 48 8b 44 24 18 64 48 2b 04 25 28 00 00 RSP: 002b:00007ffe12d544f0 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007f1cae7ab91b RDX: 0000000000000000 RSI: 0000000000004122 RDI: 0000000000000003 RBP: 00000000000001ee R08: 0000000000000073 R09: 00000000ffffffff R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000003 R13: 0000000000000001 R14: 00005584f32b1398 R15: 00005584f32b2ce8 </TASK> Allocated by task 487: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 snd_pcm_lib_malloc_pages+0x27c/0x9f0 [snd_pcm] snd_pcm_hw_params+0x171c/0x1d10 [snd_pcm] snd_pcm_common_ioctl+0x1f62/0x3aa0 [snd_pcm] snd_pcm_ioctl+0x76/0xb0 [snd_pcm] __x64_sys_ioctl+0x163/0x1d0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 499: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 snd_pcm_lib_free_pages+0x1c9/0x420 [snd_pcm] snd_pcm_common_ioctl+0x2bd3/0x3aa0 [snd_pcm] snd_pcm_ioctl+0x76/0xb0 [snd_pcm] __x64_sys_ioctl+0x163/0x1d0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f The buggy address belongs to the object at ffff888108f58580 which belongs to the cache kmalloc-64 of size 64 The buggy address is located 4 bytes inside of freed 64-byte region [ffff888108f58580, ffff888108f585c0) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x108f58 flags: 0x200000000000000(node=0|zone=2) page_type: f5(slab) raw: 0200000000000000 ffff8881000428c0 dead000000000100 dead000000000122 raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff888108f58480: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff888108f58500: 00 00 00 00 00 06 fc fc fc fc fc fc fc fc fc fc >ffff888108f58580: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ^ ffff888108f58600: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff888108f58680: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ================================================================== Disabling lock debugging due to kernel taint ------------[ cut here ]------------ kernel BUG at kernel/dma/mapping.c:417! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI CPU: 1 UID: 0 PID: 487 Comm: pcm-uaf-fixture Tainted: G B 7.2.0-rc6-pmb-alsa-functional-v2+ #1 PREEMPT(lazy) Tainted: [B]=BAD_PAGE Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:__dma_sync_sg_for_cpu+0x230/0x360 Code: df 48 c1 e8 03 80 3c 10 00 0f 85 fa 00 00 00 4c 8b 35 d4 6b 7a 09 e8 7f e2 17 00 83 fd 02 0f 86 39 fe ff ff e8 71 e2 17 00 90 <0f> 0b e8 69 e2 17 00 be 08 00 00 00 4c 89 ff e8 bc 5f 77 00 4c 89 RSP: 0018:ffff888111f3fc50 EFLAGS: 00010293 RAX: 0000000000000000 RBX: ffffffffc0250d10 RCX: ffffffff816d395f RDX: ffff88810836ba00 RSI: ffff888108f58580 RDI: ffffffffc02510d8 RBP: 00000000ffff8881 R08: 0000000000000000 R09: fffffbfff804a239 R10: ffffffffc02511cf R11: 6e696c6261736944 R12: ffff888108f58580 R13: 0000000002ce00e5 R14: ffffffffc0258720 R15: 0000000000000000 FS: 00007f1cae69c780(0000) GS:ffff8881fd861000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055d1affa2480 CR3: 0000000108fc0003 CR4: 0000000000770ef0 PKRU: 55555554 Call Trace: <TASK> snd_dma_noncontig_sync+0x15a/0x310 [snd_pcm] ? __pfx_snd_dma_noncontig_sync+0x10/0x10 [snd_pcm] snd_dma_buffer_sync+0xc9/0x110 [snd_pcm] snd_pcm_delay+0x3bd/0x550 [snd_pcm] snd_pcm_common_ioctl+0x1e7/0x3aa0 [snd_pcm] ? srso_alias_return_thunk+0x5/0xfbef5 ? do_vfs_ioctl+0x1f5/0x1280 ? __pfx_do_vfs_ioctl+0x10/0x10 ? ioctl_has_perm.constprop.0.isra.0+0x34f/0x500 ? __pfx_snd_pcm_common_ioctl+0x10/0x10 [snd_pcm] ? srso_alias_return_thunk+0x5/0xfbef5 snd_pcm_ioctl+0x76/0xb0 [snd_pcm] ? __pfx_snd_pcm_ioctl+0x10/0x10 [snd_pcm] __x64_sys_ioctl+0x163/0x1d0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f1cae7ab91b Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 1c 48 8b 44 24 18 64 48 2b 04 25 28 00 00 RSP: 002b:00007ffe12d544f0 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007f1cae7ab91b RDX: 0000000000000000 RSI: 0000000000004122 RDI: 0000000000000003 RBP: 00000000000001ee R08: 0000000000000073 R09: 00000000ffffffff R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000003 R13: 0000000000000001 R14: 00005584f32b1398 R15: 00005584f32b2ce8 </TASK> Modules linked in: snd_pcmtest snd_pcm ---[ end trace 0000000000000000 ]--- RIP: 0010:__dma_sync_sg_for_cpu+0x230/0x360 Code: df 48 c1 e8 03 80 3c 10 00 0f 85 fa 00 00 00 4c 8b 35 d4 6b 7a 09 e8 7f e2 17 00 83 fd 02 0f 86 39 fe ff ff e8 71 e2 17 00 90 <0f> 0b e8 69 e2 17 00 be 08 00 00 00 4c 89 ff e8 bc 5f 77 00 4c 89 RSP: 0018:ffff888111f3fc50 EFLAGS: 00010293 RAX: 0000000000000000 RBX: ffffffffc0250d10 RCX: ffffffff816d395f RDX: ffff88810836ba00 RSI: ffff888108f58580 RDI: ffffffffc02510d8 RBP: 00000000ffff8881 R08: 0000000000000000 R09: fffffbfff804a239 R10: ffffffffc02511cf R11: 6e696c6261736944 R12: ffff888108f58580 R13: 0000000002ce00e5 R14: ffffffffc0258720 R15: 0000000000000000 FS: 00007f1cae69c780(0000) GS:ffff8881fd861000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055d1affa2480 CR3: 0000000108fc0003 CR4: 0000000000770ef0 PKRU: 55555554 Kernel panic - not syncing: Fatal exception Kernel Offset: disabled Rebooting in 1 seconds.. Fixes: a25684a95646 ("ALSA: memalloc: Support for non-contiguous page allocation") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-d74585d187e0b1810c08-v2-25432d0951f67fdaa1a9@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
12 daysALSA: rawmidi: Drain input work before freeing the runtimeCen Zhang
The input runtime embeds event_work, so the work must be drained before close_substream() frees the runtime. The cancellation in snd_rawmidi_input_trigger() runs before close clears substream->opened, leaving a window for snd_rawmidi_receive() to enqueue more work. With a sequencer subscription to a USB MIDI input port, an in-flight completion can overlap the last subscription's midisynth_unsubscribe(): 1. snd_usbmidi_input_data() observes input_triggered and is delayed before calling snd_rawmidi_receive(). 2. Unsubscribe enters close_substream(), clears input_triggered through the provider trigger callback and returns from cancel_work_sync(). The substream is still opened. 3. The completion resumes. snd_rawmidi_receive() takes substream->lock, sees opened set and queues runtime->event_work before dropping the lock. 4. Close clears opened under that lock, closes the provider and frees the runtime. Stopping USB URBs does not drain the raw-MIDI work. 5. The queued work runs and snd_rawmidi_input_event_work() reads event or substream from the freed runtime, causing a use-after-free. Cancel input event_work again after clearing opened, before closing the provider or releasing the runtime's private data. Receive holds substream->lock through its opened check and work enqueue, so once close has cleared opened under that lock, no further receive can queue work. The final cancellation therefore drains any late work before the runtime is freed. Keep it outside the spinlock so a running callback can finish. Fixes: b3c705aa9e91 ("ALSA: rawmidi - Use workq for event handling") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-98489078ab56528d8e4a-v2-9408ce8c8f3c70b5c10d@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
12 daysALSA: jack: Remove debugfs before freeing unregistered jacksCen Zhang
Jack debugfs files store a raw snd_jack_kctl pointer, so their callbacks must be drained before the attachment is freed. snd_jack_dev_free() unlinks and frees the attachments before calling snd_jack_dev_disconnect(). Its late snd_jack_remove_debugfs() call then has no entries left to traverse. With CONFIG_SND_JACK_INJECTION_DEBUG and input support enabled, an HDA codec rebind on a live card can publish a non-phantom jack's type file while its component is still in SNDRV_DEV_BUILD. A later jack-control allocation failure permits the following order: 1. hda_codec_driver_probe() creates a jack and publishes its debugfs files before reaching snd_card_register(). 2. A later control-build failure calls snd_hda_codec_cleanup_for_unbind(), then snd_hda_jack_tbl_clear() and snd_device_free(). __snd_device_disconnect() skips BUILD components. snd_jack_dev_free() frees the attachment before its late disconnect, leaving the debugfs files published. 3. After cleanup, a reader opens the surviving type file and jack_type_read() dereferences the freed attachment's jack pointer. The card's debugfs root remains live throughout this sequence. The result is a use-after-free even without an overlapping read. An already admitted callback is also not drained by this cleanup. Call snd_jack_remove_debugfs() before unlinking any controls in the free callback. The existing debugfs_remove() rundown blocks new accesses and waits for active callbacks while the attachment, control and jack remain valid. Roots cleared by an earlier disconnect are NULL, so repeating the removal is harmless. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in jack_type_read+0x1da/0x1f0 Read of size 8 at addr ffff8881085f9da0 by task python3/429 CPU: 2 UID: 0 PID: 429 Comm: python3 Not tainted 7.2.0-rc6-pmb-alsa-functional-v2+ #1 PREEMPT(lazy) Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? jack_type_read+0x1da/0x1f0 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? jack_type_read+0x1da/0x1f0 kasan_report+0xe0/0x110 ? jack_type_read+0x1da/0x1f0 jack_type_read+0x1da/0x1f0 ? __pfx_jack_type_read+0x10/0x10 ? __pfx___debugfs_file_get+0x10/0x10 ? __pfx_cp_new_stat+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? srso_alias_return_thunk+0x5/0xfbef5 ? selinux_file_permission+0x122/0x570 full_proxy_read+0x11f/0x180 ? __pfx_full_proxy_read+0x10/0x10 vfs_read+0x1a0/0xc20 ? __pfx_vfs_read+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __do_sys_newfstat+0xa6/0x100 ? find_held_lock+0x2b/0x80 ? __pfx___do_sys_newfstat+0x10/0x10 ksys_read+0x111/0x200 ? __pfx_ksys_read+0x10/0x10 ? full_proxy_llseek+0x11e/0x170 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f7e392e7687 Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff RSP: 002b:00007fff5f7b9180 EFLAGS: 00000202 ORIG_RAX: 0000000000000000 RAX: ffffffffffffffda RBX: 00007f7e39253780 RCX: 00007f7e392e7687 RDX: 0000000000002000 RSI: 000000003d2e9b00 RDI: 0000000000000003 RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000202 R12: 00007f7e39253700 R13: 0000000000002000 R14: 00007f7e38d7e2c0 R15: 0000000000a55b98 </TASK> Allocated by task 425: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 snd_jack_kctl_new+0x80/0x180 snd_jack_new+0x4b/0x490 snd_hda_jack_add_kctl_mst+0x19b/0x610 add_jack_kctl+0x204/0x320 snd_hda_jack_add_kctls+0x212/0x910 snd_hda_gen_build_controls+0x233/0x600 snd_hda_codec_build_controls+0x2e4/0x9f0 hda_codec_driver_probe+0x26e/0x590 really_probe+0x21f/0xa90 __driver_probe_device+0x1ec/0x490 device_driver_attach+0xdc/0x210 bind_store+0xec/0x180 drv_attr_store+0x79/0xb0 sysfs_kf_write+0xed/0x140 kernfs_fop_write_iter+0x34b/0x500 vfs_write+0x637/0x1010 ksys_write+0x111/0x200 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 425: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 snd_jack_kctl_private_free+0x153/0x200 __snd_ctl_remove+0x29f/0x3b0 snd_ctl_remove+0x46/0x70 snd_jack_dev_free+0x1b1/0x370 __snd_device_free+0x193/0x3f0 snd_device_free+0xcf/0x190 snd_hda_jack_tbl_clear+0x159/0x2e0 snd_hda_codec_cleanup_for_unbind+0x37e/0x9c0 hda_codec_driver_probe+0x3ae/0x590 really_probe+0x21f/0xa90 __driver_probe_device+0x1ec/0x490 device_driver_attach+0xdc/0x210 bind_store+0xec/0x180 drv_attr_store+0x79/0xb0 sysfs_kf_write+0xed/0x140 kernfs_fop_write_iter+0x34b/0x500 vfs_write+0x637/0x1010 ksys_write+0x111/0x200 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f The buggy address belongs to the object at ffff8881085f9d80 which belongs to the cache kmalloc-64 of size 64 The buggy address is located 32 bytes inside of freed 64-byte region [ffff8881085f9d80, ffff8881085f9dc0) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1085f9 flags: 0x200000000000000(node=0|zone=2) page_type: f5(slab) raw: 0200000000000000 ffff8881000428c0 dead000000000100 dead000000000122 raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff8881085f9c80: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc ffff8881085f9d00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc >ffff8881085f9d80: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ^ ffff8881085f9e00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff8881085f9e80: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ================================================================== Fixes: 495000a38634 ("ALSA: core: Remove debugfs at disconnection") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-e1e7490bbe7ba1b3c44a-v2-3e3b6315a18c02ced60d@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
12 daysALSA: control_led: Fix deadlock between sysfs writes and card disconnectAli Ahmet Memiş
snd_ctl_led_disconnect() removes the ctl-led sysfs files while holding card->controls_rwsem. device_unregister() waits for running sysfs callbacks which can deadlock when a concurrent write causes the attach or detach callback to wait for controls_rwsem. Break kernfs active protection in the attach, detach and list callbacks and hold a module reference instead. Fixes: a135dfb5de15 ("ALSA: led control - add sysfs kcontrol LED marking layer") Signed-off-by: Ali Ahmet Memiş <aliamemis@disroot.org> Link: https://patch.msgid.link/20261011180627.1594051-1-aliamemis@disroot.org Signed-off-by: Takashi Iwai <tiwai@suse.de>
13 daysALSA: timer: Pin the module for userspace timer controllersCen Zhang
The static snd_utimer_ids IDA must remain live until a userspace timer controller has returned its ID. However, snd_utimer_fops has no owner, so anon_inode_getfd() does not take a reference to snd-timer for the controller file. With CONFIG_SND_TIMER=m and CONFIG_SND_UTIMER=y, userspace can create a controller with SNDRV_TIMER_IOCTL_CREATE and close the native timer file. If no timer instances or dependent modules retain snd-timer, ordinary module unload can then overlap the controller's final release: Controller final release Module unload snd_utimer_release() snd_utimer_free() snd_timer_free(): unlink provider snd_utimer_put_id() enter ida_free() delete_module() alsa_timer_exit() free_module(): free MOD_DATA access snd_utimer_ids.xa The provider is already absent from snd_timer_free_all() when unload runs. Neither register_mutex nor the IDA's lock keeps module storage resident through the remaining IDA access. That access can therefore use freed module data and fault while acquiring the XArray lock, as shown in the Oops below. Set snd_utimer_fops.owner to THIS_MODULE so anonymous-file creation takes the existing module reference. The VFS drops it only after snd_utimer_release() returns, keeping the IDA resident through ida_free() and preventing ordinary unload during that interval. Oops report as below: BUG: unable to handle page fault for address: fffffbfff80480af #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 1a7ff6067 P4D 1a7ff6067 PUD 1a7ff2067 PMD 100ad6067 PTE 0 Oops: Oops: 0000 [#1] SMP KASAN NOPTI CPU: 0 UID: 0 PID: 485 Comm: alsa-utimer-fix Tainted: G O 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) Tainted: [O]=OOT_MODULE Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:kasan_byte_accessible+0x15/0x30 Code: 00 00 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 40 d6 48 b8 00 00 00 00 00 fc ff df 48 c1 ef 03 48 01 c7 <0f> b6 07 3c 07 0f 96 c0 e9 69 f1 2b ff 66 66 2e 0f 1f 84 00 00 00 RSP: 0018:ffff88811a457c48 EFLAGS: 00010086 RAX: dffffc0000000000 RBX: ffffffffc0240578 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff861f111c RDI: fffffbfff80480af RBP: ffffffffc0240578 R08: 0000000000000001 R09: 0000000000000000 R10: ffffffff891cc057 R11: ffff88811531ba00 R12: ffffffff861f111c R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 FS: 00007ff190ff7780(0000) GS:ffff8881fda2a000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: fffffbfff80480af CR3: 0000000116890003 CR4: 0000000000770ef0 PKRU: 55555554 Call Trace: <TASK> __kasan_check_byte+0x13/0x50 lock_acquire+0x113/0x2f0 ? __pfx_pmbd_probe_hit_cookie+0x10/0x10 ? lock_release+0xc8/0x280 ? srso_alias_return_thunk+0x5/0xfbef5 _raw_spin_lock_irqsave+0x3c/0x60 ? ida_free+0xd4/0x2b0 ida_free+0xd4/0x2b0 ? __pfx_ida_free+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_locks_remove_file+0x10/0x10 ? __fput+0x39f/0xa60 ? fput_close_sync+0xff/0x200 ? __pfx_fput_close_sync+0x10/0x10 ? dnotify_flush+0x22/0x4b0 ? __x64_sys_close+0x8c/0xf0 ? do_syscall_64+0x115/0x6a0 ? entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> Modules linked in: snd(O) [last unloaded: snd_timer(O)] CR2: fffffbfff80480af ---[ end trace 0000000000000000 ]--- Fixes: 37745918e0e7 ("ALSA: timer: Introduce virtual userspace-driven timers") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Link: https://patch.msgid.link/pm-pmb-98fb8f747fc7b8499fd4-v2-1c531f149a6d6c084f48@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
14 daysALSA: seq: Wait for one RCU grace period when deleting all portsAli Ahmet Memiş
Since the port list was converted to RCU, snd_seq_delete_all_ports() calls synchronize_rcu() once per port under register_mutex. Closing a client with 254 ports now takes about 1.6s and every other client open or close waits for it. Unlink all ports first, wait for a single grace period and then free them. Fixes: 4c252fbc06d6 ("ALSA: seq: Use RCU for the client port list") Signed-off-by: Ali Ahmet Memiş <aliamemis@disroot.org> Link: https://patch.msgid.link/20261010222543.1470723-1-aliamemis@disroot.org Signed-off-by: Takashi Iwai <tiwai@suse.de>
2026-10-08ALSA: seq: Don't lose partial read failureTakashi Iwai
snd_seq_read() returns an error even if one or more events have been successfully read before the error (except for -EAGAIN case), but this rather doesn't follow the POSIX standard that wants the processed bytes. Change the behavior to return the processed bytes when it's positive, instead. Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20261007172533.14667-8-tiwai@suse.de
2026-10-08ALSA: core: Fix leaks at snd_card_init() error pathsTakashi Iwai
When the snd_card object is initialized internally in snd_card_init(), the error path of card->value_buf allocation returns straightly as an error without invoking the destructor, which would leak resources. Also, the other error paths in snd_card_init() release the card object only via put_device(), and this misses the cleanups that are done in snd_card_disconnect(); namely, the reserved slot bit in snd_cards_lock is never cleared, so the card index remains occupied, and the debugfs directory created for the card is left over. Fix them by calling snd_card_free() at the error path, which performs both the disconnection and the release properly. As snd_card_free() calls snd_device_free_all() internally, the explicit call is dropped, and the error labels are unified. Fixes: 84446536f63d ("ALSA: control: Verify put() result when in debug mode") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20261007172533.14667-7-tiwai@suse.de
2026-10-08ALSA: info: Fix memory leak at card removalTakashi Iwai
The fix for potential deadlock at disconnection by the commit c7a606519533 ("ALSA: info: Fix potential deadlock at disconnection") clears card->proc_root pointer at snd_info_card_disconnect(), in order just to be sure. But this leads to a memory leak of card->proc_root content that should have been released at a later call of snd_info_card_free(). For addressing the memory leak, simply drop the card->proc_root clearance at snd_info_card_disconnect(). Since card->proc_root might be still looked at in snd_info_card_id_change() that may be running concurrently during the connection procedure, add a sanity check there, too. Fixes: c7a606519533 ("ALSA: info: Fix potential deadlock at disconnection") Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20261006174002.703431-1-tiwai%40suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20261007172533.14667-5-tiwai@suse.de
2026-10-08ALSA: seq: Fix missing direction and ump_group handling in 32bit compat ioctlTakashi Iwai
I forgot to cover the two new fields, direction and ump_group, in struct snd_seq_port_info for the 32bit compat ioctls of SNDRV_SEQ_IOCTL_GET_PORT_INFO & co, which ended up with the garbage copies in those fields. Add the handling of those two fields in the compat layer. Also, avoid over-copying the 64bit snd_seq_port_info but only the first part (before the field kernel); this avoids the copy of kernel-space garbage value in the reserved field. Fixes: ff166a9d19fa ("ALSA: seq: Add port direction to snd_seq_port_info") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20261007172533.14667-2-tiwai@suse.de
2026-10-08ALSA: core: Add missing barriers for power_ref vs card->shutdownTakashi Iwai
snd_power_ref_and_wait() increments card->power_ref and then reads card->shutdown (and the power state) locklessly, while snd_card_disconnect() sets card->shutdown and then waits for power_ref to drop to zero via snd_power_sync_ref(). Due to the missing barrier on both sides, the caller proceeds with shutdown still seen as false, while the disconnect side sees a zero refcount and continues tearing down incorrectly. For addressing the potential race, add smp_mb__after_atomic() after the refcount increment and smp_mb() before snd_power_sync_ref() in snd_card_disconnect(). Fixes: e94fdbd7b25d ("ALSA: control: Track in-flight control read/write/tlv accesses") Reported-by: Sashiko <sashiko-bot@kernel.org> Assisted-by: LLM Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20261007172051.13240-9-tiwai@suse.de
2026-10-08ALSA: pcm: Fix TOCTOU state overwrite in snd_pcm_drop()Takashi Iwai
snd_pcm_drop() checks the current state at the beginning, and bails out if it's in an invalid state (OPEN or DISCONNECTED). However, since the check is done before the PCM stream lock, this can lead to a Time-of-Check to Time-of-Use (TOCTOU) race against the other forcible state change like the device disconnection like below: CPU 0 CPU 1 ----- ----- snd_pcm_drop() runtime->state check snd_pcm_dev_disconnect() guard(pcm_stream_lock_irq) runtime->state = SNDRV_PCM_STATE_DISCONNECTED guard(pcm_stream_lock_irq) snd_pcm_stop(SNDRV_PCM_STATE_SETUP) <== inconsistent state For avoiding the inconsistent state change, this patch moves the runtime state check inside the stream lock guard. Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20261007172051.13240-3-tiwai@suse.de
2026-10-08ALSA: seq: Drop the bogus RCU guard from clientptr()Takashi Iwai
In the recent refactoring with RCU, clientptr() takes guard(rcu)() around the client table lookup, but the RCU read-side section ends as soon as the function returns, so the returned pointer isn't protected at all. This gives a false impression as if that the callers were safe, and confuse reviewers including Sashiko. Actually, the callers (snd_seq_delete_kernel_client(), snd_seq_kernel_client_ctl() and snd_seq_kernel_client_write_poll()) never relied on any lock; the caller is the owner of the client (a kernel client passing its own id, or a user client via its opened file), hence the client can't be released concurrently by others. So just drop the confusing and useless RCU guard, read the table via rcu_dereference_protected(), and document the lifetime rule. Along with it, fold __clientptr() into its only user client_use_ptr(); the id range is already checked there, and it's never called with clients_lock held, so a plain rcu_dereference() suffices. Fixes: 7a287e4615d6 ("ALSA: seq: Use RCU for the client table") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20261007172051.13240-2-tiwai@suse.de
2026-10-07ALSA: compress: Set the draining state before the drain triggerPeter Ujfalusi
The state of the stream is set to SNDRV_PCM_STATE_DRAINING only after the drain trigger has been sent to the driver. Drivers can not block in the trigger callback and the drain is completed asynchronously: snd_compr_drain_notify() can be called either from the trigger callback itself or from a different context as soon as the trigger returns. If that happens before the core updates the state then the notification is lost: the state is overwritten with DRAINING right after it and the wait for the drain to complete will not be woken up. Set the state before the trigger is issued and restore it if the trigger fails. The partial_drain flag is cleared on the error path as well as it would otherwise be left set for the next drain. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://patch.msgid.link/20261007084955.1256-5-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
2026-10-07ALSA: compress: stop active streams on disconnectPeter Ujfalusi
Track open compressed streams per device so disconnect can stop active streams and wake waiters before snd_unregister_device(). This aligns compressed stream teardown with PCM disconnect behavior and prevents active userspace streams from running into unregister races. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com> Reviewed-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20261007084955.1256-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
2026-10-07ALSA: compress: register the open file with the cardPeter Ujfalusi
The compress-offload device is the only ALSA character device family which does not add its open files to the card's file list. Without it the core cannot replace the file operations on disconnect, so syscalls issued after the card is gone still reach the driver, and a card freed with snd_card_free_when_closed() does not wait for the open compress streams. Call snd_card_file_add() at open and snd_card_file_remove() at release, following the ordering used by the PCM, control, rawmidi and hwdep devices. Suggested-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20261007084955.1256-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
2026-10-07ALSA: compress: pin card module while stream is openPeter Ujfalusi
Take a module reference in snd_compr_open() and release it in snd_compr_free(). This pins the card driver module for the lifetime of an open compress stream and prevents card removal while the stream file is still in use. Adjust the open() cleanup paths to drop the added module reference only when it was acquired, and keep release ordering safe by dropping the module reference before freeing stream data. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com> Reviewed-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20261007084955.1256-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
2026-10-03ALSA: pcm: Optimize cpu_latency_qos_*() callsTakashi Iwai
We have a few cpu_latency_qos_*() calls in PCM callbacks, but they seem suboptimal in a few aspects: - We call them at each time when the hw_params changed, but explicitly do remove and (re-)add; this could be cpu_latency_qos_update_request(), instead - The setup of cpu_latency_qos_*() doesn't have to be in hw_params at all; it's not the place where the actual parameters are set up, but rather better at the prepare callback. - The hw_free calls cpu_latency_qos_remove_request() unconditionally, which may be poking a WARNING when it wasn't queued. For addressing the issues above, this patch cleans up and reorganize the cpu_latency_qos_*() calls in the PCM core by a couple helper functions. Now, they are set up at prepare callback, and cleared at hw_free and release callbacks via the new helpers. Link: https://patch.msgid.link/20261002150420.879056-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>