All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: 徐晗翔 <xuhx@hust.edu.cn>
Cc: perex@perex.cz, tiwai@suse.com, linux-sound@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: ALSA: ctxfi: free atimer only after the timer IRQ is quiesced
Date: Fri, 13 Nov 2026 17:30:54 +0100	[thread overview]
Message-ID: <87ik20publ.wl-tiwai@suse.de> (raw)
In-Reply-To: <57529fbf.262c8.1a1d4c65987.Coremail.xuhx@hust.edu.cn>

On Fri, 13 Nov 2026 12:58:51 +0100,
徐晗翔 wrote:
> 
> `ct_timer_free()` frees `struct ct_timer` while the ctxfi timer IRQ handler can
> still be executing, or can start after `snd_card_disconnect()` has already done
> its single `synchronize_irq()`.  A handler that has passed the non-atomic
> `hw->irq_callback` check then calls `ct_timer_interrupt()` with the freed
> `atimer`; `free_irq()` only runs later, inside `ct_atc_destroy()` ->
> `destroy_hw_obj()`.  This is a use-after-free on the timer object and can crash
> or wedge the device during PCI removal/unbind.
> 
> The detailed description:
> 
> * Test environment / affected version
> 
>   Linux 7.3.0 source tree under review.  This report is source-level only: no
>   ctxfi hardware was available and QEMU has no ctxfi device model, so no
>   driver-specific reproducer was run.  The source paths/line numbers below are
>   from 7.3.
> 
> * Mechanism
> 
>   `ct_timer_new()` (`sound/pci/ctxfi/cttimer.c:388-411`) installs the native
>   timer callback by default when `!use_system_timer && hw->set_timer_irq`:
> 
>     hw->irq_callback_data = atimer;
>     hw->irq_callback      = ct_timer_interrupt;
> 
>   The PCI IRQ handlers `ct_20k1_interrupt()` (`cthw20k1.c:1878-1891`) and
>   `ct_20k2_interrupt()` (`cthw20k2.c:2045-2059`) do:
> 
>     if (hw->irq_callback)
>         hw->irq_callback(hw->irq_callback_data, status);
> 
>   `ct_timer_interrupt()` (`cttimer.c:379-386`) then reads
>   `timer->ops->interrupt` and calls it with `timer`.  Neither the check nor
>   the two loads is atomic.
> 
>   `ct_timer_free()` (`cttimer.c:414-421`) does:
> 
>     struct hw *hw = atimer->atc->hw;
>     hw->irq_callback = NULL;
>     if (atimer->ops->free_global)
>         atimer->ops->free_global(atimer);
>     kfree(atimer);
> 
>   `ct_xfitimer_free_global()` only calls `ct_xfitimer_irq_stop()`; that helper
>   stops the hardware only if `atimer->running` is set (`cttimer.c:137-145`).
>   It does not wait for an in-flight IRQ handler.
> 
>   `ct_atc_destroy()` (`ctatc.c:1250-1286`) then calls `ct_timer_free()` at
>   1257-1260, calls `destroy_hw_obj(atc->hw)` at 1274-1275, and only after that
>   `kfree(atc)` at 1283.  `destroy_hw_obj()` -> `hw_card_shutdown()` ->
>   `free_irq()` at `cthw20k1.c:1969` / `cthw20k2.c:2140`.  So `atc` itself is
>   not the freed object in this window; `atimer` is freed before `free_irq()`.
> 
> * Why the existing synchronization does not close the window
> 
>   ctxfi does set `card->sync_irq` at `cthw20k1.c:1937` / `cthw20k2.c:2104`,
>   and `snd_card_disconnect()` (`sound/core/init.c:495-562`) calls
>   `synchronize_irq(card->sync_irq)` once at 540-541.  But that call happens
>   before `ct_timer_free()`, only waits handlers that are running at that
>   instant, and does not disable the IRQ line.  A new handler can enter after
>   the one-time sync and before `free_irq()`.
> 
>   The `hw->irq_callback = NULL` store does not close the race either: a
>   handler that loaded the callback pointer before the store can still call it.
> 
> * Trigger model
> 
>   Open a ctxfi device (native timer path, the default), then remove/unbind the
>   PCI device while an interrupt is pending or arrives during teardown.  The
>   window is between `ct_timer_free()` and `free_irq()`.  Consequence: UAF read
>   of `atimer->ops` and timer fields in IRQ context; crash, stall, or potential
>   control-flow corruption.
> 
> * Suggested direction
> 
>   After clearing `hw->irq_callback` and calling `free_global()`, but before
>   `kfree(atimer)`, do:
> 
>     if (hw->irq >= 0)
>         synchronize_irq(hw->irq);
> 
>   Alternatively, move `free_irq()` earlier so it precedes the timer free.
>   Keep the existing `hw->irq == -1` initialization contract.
> 
> 
> Please keep me in Cc; I am not subscribed to the lists.

Could you rather submit a fix patch (with a proper patch description)
for each your reported issue?  You can put Link: tag to pointing to
the earlier reports.


thanks,

Takashi

  reply	other threads:[~2026-11-13 16:30 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-27 12:35 usb: devio: usbdev_release() has no barrier against an in-flight async_completed() callback (use-after-free window on struct usb_dev_state)gregkh@linuxfoundation.org 徐晗翔
2026-10-27 14:12 ` Greg KH
2026-11-03 11:21   ` mm/slub: has_pcs_used() reads remote per-CPU sheaf state from flush_all_cpus_locked() without synchronization (data race; KCSAN blind spot: slub.o is uninstrumented) 徐晗翔
2026-11-04  9:41     ` Qing Wang
2026-11-04 10:07       ` Qing Wang
2026-11-03 11:30   ` futex/hrtimer: hrtimer_sleeper::task is read unsynchronized in 16 places on v7.3 -- the accessor series that fixes this is not in 7.3; please make sure it reaches the affected trees (backport nudge + stock-kernel KCSAN evidence) 徐晗翔
2026-11-03 11:48   ` cgroup: fork vs cgroup.procs write race in favordynmods mode -- v7.3 is affected; please make sure bf6fbf46b5ff reaches the stable trees (repro incl. uninstrumented natural hit) 徐晗翔
2026-11-03 14:51     ` Sasha Levin
2026-11-03 11:57   ` net: rtnetlink: rtnl_link_unregister() vs in-flight RTM_GETLINK dump readers -- v7.3 lacks the synchronize_rcu() fix (Fixes: 6b57ff21a310 family); A/B reproduction on stock 7.3 徐晗翔
2026-11-03 15:49     ` Eric Dumazet
2026-11-04 15:03     ` Sasha Levin
2026-11-03 12:07   ` wifi: wilc1000: SDIO/SPI remove destroys the srcu_struct before wiphy_unregister() -- late cfg80211 callbacks write through dangling srcu state (unfixed upstream; controlled + natural Oops) 徐晗翔
2026-11-03 12:10   ` gpio: gpiolib: final put of the gpio_device happens inside the SRCU read critical section on the setup-failure path -- deterministic use-after-free read at guard release (unfixed upstream) 徐晗翔
2026-11-05  8:52     ` Linus Walleij
2026-11-04 12:54   ` soc: qcom: pmic_glink_altmode: fix use-after-free on unbind (no cancel_work_sync for port work and enable_work) 徐晗翔
2026-11-04 13:04     ` Greg KH
2026-11-04 12:57   ` usb: typec: anx7411: unregister partner/altmodes before stopping the IRQ work -- use-after-free, double unregister, orphan partner on remove 徐晗翔
2026-11-04 13:28     ` Greg KH
2026-11-04 12:58   ` usb: typec: ucsi: deadlock on cros_ec unbind -- connector lock held across cancel_delayed_work_sync vs the mode-selection work's unbounded trylock polling 徐晗翔
2026-11-04 13:00   ` usb: typec: stusb160x/rt1719/hd3ss3220: IRQ thread vs remove -- double unregister / use-after-free on the partner and port 徐晗翔
2026-11-04 13:01   ` usb: typec: ucsi: displayport: data race on dp->header/ vdo_data/vdo_size -- work reads them unlocked while writers hold con->lock (VDM mismatch) 徐晗翔
2026-11-04 13:02   ` usb: typec: class: three lifetime/locking gaps around the mux/switch handles and mode_selection (drvdata UAF after provider unbind; no concurrent protocol for set/put; unlocked state_update vs delete) 徐晗翔
2026-11-10 12:56   ` driver core: uevent: netns teardown frees uevent_sock while a tagged uevent is still being broadcast (UAF) 徐晗翔
2026-11-10 13:00   ` 徐晗翔
2026-11-10 18:48     ` Greg KH
2026-11-10 13:05   ` ACPI: CPPC: per-CPU cpc_desc is freed on processor unbind without clearing the published pointer, causing UAF in cpufreq accessors 徐晗翔
2026-11-10 13:07   ` ACPI: CPPC: shared PCC subspace data can be freed while another CPU probes, reads, or tears it down 徐晗翔
2026-11-10 14:47     ` Christian Loehle
2026-11-10 13:11   ` ACPI: ACPICA: Reset can delete an event semaphore while another thread is blocked in Wait 徐晗翔
2026-11-10 13:14   ` power: supply: bq25890: pump-express work can call power_supply_changed after the psy is unregistered 徐晗翔
2026-11-10 13:17   ` power: supply: core: get/set property callbacks can run after unregister and read freed driver data 徐晗翔
2026-11-10 13:18   ` power: supply: core: system-battery enumeration can return an unregistered battery 徐晗翔
2026-11-10 13:21   ` power: supply: core: changed work can run after unregister and use freed LED triggers 徐晗翔
2026-11-10 13:23   ` power: supply: bq24190: IRQ handler can call power_supply_changed after the psy is unregistered 徐晗翔
2026-11-10 13:34   ` 徐晗翔
2026-11-11  7:17   ` genirq: NMI dispatch reads struct irqaction with no quiescence -- use-after-free across free_nmi()'s kfree (x86 verification on the arch-independent core path) 徐晗翔
2026-11-11  7:26   ` genirq: NMI API lacks the request_mutex / dev_id matching / idempotency semantics that free_irq() has -- double free_nmi releases chip PM and module references twice (verified) 徐晗翔
2026-11-11  7:30   ` kernfs: kernfs_drain()'s fast-path decision reads the active count without acquire ordering -- on weakly-ordered architectures the forced ->release()/unmap can be skipped 徐晗翔
2026-11-11 13:41     ` Greg KH
2026-11-13 11:58   ` ALSA: ctxfi: free atimer only after the timer IRQ is quiesced 徐晗翔
2026-11-13 16:30     ` Takashi Iwai [this message]
2026-11-13 12:03   ` ALSA: ctxfi: do not free a running system timer when timer_delete_sync_try() returns -1 (UAF) 徐晗翔
2026-11-13 12:04   ` ALSA: asihpi: free IRQ before snd_card_free()/HPI delete on HPI6205 removal (UAF) 徐晗翔
2026-11-13 12:06   ` ALSA: asihpi: quiesce PCM timer and IRQ before freeing dpcm on close (UAF) 徐晗翔
2026-11-13 12:15   ` ALSA: pcm: link-group walk in timer callback can use a closed substream's freed runtime (UAF) 徐晗翔
2026-11-13 12:28   ` ALSA: usb-audio: us144mkii: PCM close frees runtime while playback/feedback URB completion and capture work still use it (UAF) 徐晗翔
2026-11-13 12:29   ` ALSA: usb-audio: us144mkii: queued stop_pcm_work calls snd_pcm_stop() after PCM close and dereferences NULL runtime 徐晗翔
2026-11-13 12:33   ` sched/topology: old domain chains are queued for RCU freeing before the per-CPU pointers are updated, so a late reader can still dereference a freed sched_domain and sched_domain_shared (UAF) 徐晗翔
2026-11-13 12:47   ` xfs: use-after-free in stats_clear sysctl handler during module unload 徐晗翔
2026-11-13 12:48   ` xfs: data races on xfs_params and xfs_globals tunables 徐晗翔

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ik20publ.wl-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    --cc=xuhx@hust.edu.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.