* [PATCH net] net: wan: farsync: Fix use-after-free bugs caused by unfinished tasklets
@ 2026-02-19 12:46 Duoming Zhou
2026-02-24 8:34 ` Jijie Shao
2026-02-24 9:40 ` patchwork-bot+netdevbpf
0 siblings, 2 replies; 3+ messages in thread
From: Duoming Zhou @ 2026-02-19 12:46 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kevin.curtis, andrew+netdev, davem, edumazet, kuba,
pabeni, Duoming Zhou
When the FarSync T-series card is being detached, the fst_card_info is
deallocated in fst_remove_one(). However, the fst_tx_task or fst_int_task
may still be running or pending, leading to use-after-free bugs when the
already freed fst_card_info is accessed in fst_process_tx_work_q() or
fst_process_int_work_q().
A typical race condition is depicted below:
CPU 0 (cleanup) | CPU 1 (tasklet)
| fst_start_xmit()
fst_remove_one() | tasklet_schedule()
unregister_hdlc_device()|
| fst_process_tx_work_q() //handler
kfree(card) //free | do_bottom_half_tx()
| card-> //use
The following KASAN trace was captured:
==================================================================
BUG: KASAN: slab-use-after-free in do_bottom_half_tx+0xb88/0xd00
Read of size 4 at addr ffff88800aad101c by task ksoftirqd/3/32
...
Call Trace:
<IRQ>
dump_stack_lvl+0x55/0x70
print_report+0xcb/0x5d0
? do_bottom_half_tx+0xb88/0xd00
kasan_report+0xb8/0xf0
? do_bottom_half_tx+0xb88/0xd00
do_bottom_half_tx+0xb88/0xd00
? _raw_spin_lock_irqsave+0x85/0xe0
? __pfx__raw_spin_lock_irqsave+0x10/0x10
? __pfx___hrtimer_run_queues+0x10/0x10
fst_process_tx_work_q+0x67/0x90
tasklet_action_common+0x1fa/0x720
? hrtimer_interrupt+0x31f/0x780
handle_softirqs+0x176/0x530
__irq_exit_rcu+0xab/0xe0
sysvec_apic_timer_interrupt+0x70/0x80
...
Allocated by task 41 on cpu 3 at 72.330843s:
kasan_save_stack+0x24/0x50
kasan_save_track+0x17/0x60
__kasan_kmalloc+0x7f/0x90
fst_add_one+0x1a5/0x1cd0
local_pci_probe+0xdd/0x190
pci_device_probe+0x341/0x480
really_probe+0x1c6/0x6a0
__driver_probe_device+0x248/0x310
driver_probe_device+0x48/0x210
__device_attach_driver+0x160/0x320
bus_for_each_drv+0x101/0x190
__device_attach+0x198/0x3a0
device_initial_probe+0x78/0xa0
pci_bus_add_device+0x81/0xc0
pci_bus_add_devices+0x7e/0x190
enable_slot+0x9b9/0x1130
acpiphp_check_bridge.part.0+0x2e1/0x460
acpiphp_hotplug_notify+0x36c/0x3c0
acpi_device_hotplug+0x203/0xb10
acpi_hotplug_work_fn+0x59/0x80
...
Freed by task 41 on cpu 1 at 75.138639s:
kasan_save_stack+0x24/0x50
kasan_save_track+0x17/0x60
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x43/0x70
kfree+0x135/0x410
fst_remove_one+0x2ca/0x540
pci_device_remove+0xa6/0x1d0
device_release_driver_internal+0x364/0x530
pci_stop_bus_device+0x105/0x150
pci_stop_and_remove_bus_device+0xd/0x20
disable_slot+0x116/0x260
acpiphp_disable_and_eject_slot+0x4b/0x190
acpiphp_hotplug_notify+0x230/0x3c0
acpi_device_hotplug+0x203/0xb10
acpi_hotplug_work_fn+0x59/0x80
...
The buggy address belongs to the object at ffff88800aad1000
which belongs to the cache kmalloc-1k of size 1024
The buggy address is located 28 bytes inside of
freed 1024-byte region
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xaad0
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0x100000000000040(head|node=0|zone=1)
page_type: f5(slab)
raw: 0100000000000040 ffff888007042dc0 dead000000000122 0000000000000000
raw: 0000000000000000 0000000080100010 00000000f5000000 0000000000000000
head: 0100000000000040 ffff888007042dc0 dead000000000122 0000000000000000
head: 0000000000000000 0000000080100010 00000000f5000000 0000000000000000
head: 0100000000000003 ffffea00002ab401 00000000ffffffff 00000000ffffffff
head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88800aad0f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88800aad0f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff88800aad1000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff88800aad1080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88800aad1100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
Fix this by ensuring that both fst_tx_task and fst_int_task are properly
canceled before the fst_card_info is released. Add tasklet_kill() in
fst_remove_one() to synchronize with any pending or running tasklets.
Since unregister_hdlc_device() stops data transmission and reception,
and fst_disable_intr() prevents further interrupts, it is appropriate
to place tasklet_kill() after these calls.
The bugs were identified through static analysis. To reproduce the issue
and validate the fix, a FarSync T-series card was simulated in QEMU and
delays(e.g., mdelay()) were introduced within the tasklet handler to
increase the likelihood of triggering the race condition.
Fixes: 2f623aaf9f31 ("net: farsync: Fix kmemleak when rmmods farsync")
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
---
drivers/net/wan/farsync.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 5b01642ca44..6b2d1e63855 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -2550,6 +2550,8 @@ fst_remove_one(struct pci_dev *pdev)
fst_disable_intr(card);
free_irq(card->irq, card);
+ tasklet_kill(&fst_tx_task);
+ tasklet_kill(&fst_int_task);
iounmap(card->ctlmem);
iounmap(card->mem);
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH net] net: wan: farsync: Fix use-after-free bugs caused by unfinished tasklets
2026-02-19 12:46 [PATCH net] net: wan: farsync: Fix use-after-free bugs caused by unfinished tasklets Duoming Zhou
@ 2026-02-24 8:34 ` Jijie Shao
2026-02-24 9:40 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 3+ messages in thread
From: Jijie Shao @ 2026-02-24 8:34 UTC (permalink / raw)
To: Duoming Zhou, netdev
Cc: shaojijie, linux-kernel, kevin.curtis, andrew+netdev, davem,
edumazet, kuba, pabeni
on 2026/2/19 20:46, Duoming Zhou wrote:
> When the FarSync T-series card is being detached, the fst_card_info is
> deallocated in fst_remove_one(). However, the fst_tx_task or fst_int_task
> may still be running or pending, leading to use-after-free bugs when the
> already freed fst_card_info is accessed in fst_process_tx_work_q() or
> fst_process_int_work_q().
>
> A typical race condition is depicted below:
>
> CPU 0 (cleanup) | CPU 1 (tasklet)
> | fst_start_xmit()
> fst_remove_one() | tasklet_schedule()
> unregister_hdlc_device()|
> | fst_process_tx_work_q() //handler
> kfree(card) //free | do_bottom_half_tx()
> | card-> //use
>
> The following KASAN trace was captured:
>
> ==================================================================
> BUG: KASAN: slab-use-after-free in do_bottom_half_tx+0xb88/0xd00
> Read of size 4 at addr ffff88800aad101c by task ksoftirqd/3/32
> ...
> Call Trace:
> <IRQ>
> dump_stack_lvl+0x55/0x70
> print_report+0xcb/0x5d0
> ? do_bottom_half_tx+0xb88/0xd00
> kasan_report+0xb8/0xf0
> ? do_bottom_half_tx+0xb88/0xd00
> do_bottom_half_tx+0xb88/0xd00
> ? _raw_spin_lock_irqsave+0x85/0xe0
> ? __pfx__raw_spin_lock_irqsave+0x10/0x10
> ? __pfx___hrtimer_run_queues+0x10/0x10
> fst_process_tx_work_q+0x67/0x90
> tasklet_action_common+0x1fa/0x720
> ? hrtimer_interrupt+0x31f/0x780
> handle_softirqs+0x176/0x530
> __irq_exit_rcu+0xab/0xe0
> sysvec_apic_timer_interrupt+0x70/0x80
> ...
>
> Allocated by task 41 on cpu 3 at 72.330843s:
> kasan_save_stack+0x24/0x50
> kasan_save_track+0x17/0x60
> __kasan_kmalloc+0x7f/0x90
> fst_add_one+0x1a5/0x1cd0
> local_pci_probe+0xdd/0x190
> pci_device_probe+0x341/0x480
> really_probe+0x1c6/0x6a0
> __driver_probe_device+0x248/0x310
> driver_probe_device+0x48/0x210
> __device_attach_driver+0x160/0x320
> bus_for_each_drv+0x101/0x190
> __device_attach+0x198/0x3a0
> device_initial_probe+0x78/0xa0
> pci_bus_add_device+0x81/0xc0
> pci_bus_add_devices+0x7e/0x190
> enable_slot+0x9b9/0x1130
> acpiphp_check_bridge.part.0+0x2e1/0x460
> acpiphp_hotplug_notify+0x36c/0x3c0
> acpi_device_hotplug+0x203/0xb10
> acpi_hotplug_work_fn+0x59/0x80
> ...
>
> Freed by task 41 on cpu 1 at 75.138639s:
> kasan_save_stack+0x24/0x50
> kasan_save_track+0x17/0x60
> kasan_save_free_info+0x3b/0x60
> __kasan_slab_free+0x43/0x70
> kfree+0x135/0x410
> fst_remove_one+0x2ca/0x540
> pci_device_remove+0xa6/0x1d0
> device_release_driver_internal+0x364/0x530
> pci_stop_bus_device+0x105/0x150
> pci_stop_and_remove_bus_device+0xd/0x20
> disable_slot+0x116/0x260
> acpiphp_disable_and_eject_slot+0x4b/0x190
> acpiphp_hotplug_notify+0x230/0x3c0
> acpi_device_hotplug+0x203/0xb10
> acpi_hotplug_work_fn+0x59/0x80
> ...
>
> The buggy address belongs to the object at ffff88800aad1000
> which belongs to the cache kmalloc-1k of size 1024
> The buggy address is located 28 bytes inside of
> freed 1024-byte region
> The buggy address belongs to the physical page:
> page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xaad0
> head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
> flags: 0x100000000000040(head|node=0|zone=1)
> page_type: f5(slab)
> raw: 0100000000000040 ffff888007042dc0 dead000000000122 0000000000000000
> raw: 0000000000000000 0000000080100010 00000000f5000000 0000000000000000
> head: 0100000000000040 ffff888007042dc0 dead000000000122 0000000000000000
> head: 0000000000000000 0000000080100010 00000000f5000000 0000000000000000
> head: 0100000000000003 ffffea00002ab401 00000000ffffffff 00000000ffffffff
> head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
> page dumped because: kasan: bad access detected
>
> Memory state around the buggy address:
> ffff88800aad0f00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> ffff88800aad0f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >ffff88800aad1000: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ^
> ffff88800aad1080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ffff88800aad1100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ==================================================================
>
> Fix this by ensuring that both fst_tx_task and fst_int_task are properly
> canceled before the fst_card_info is released. Add tasklet_kill() in
> fst_remove_one() to synchronize with any pending or running tasklets.
> Since unregister_hdlc_device() stops data transmission and reception,
> and fst_disable_intr() prevents further interrupts, it is appropriate
> to place tasklet_kill() after these calls.
>
> The bugs were identified through static analysis. To reproduce the issue
> and validate the fix, a FarSync T-series card was simulated in QEMU and
> delays(e.g., mdelay()) were introduced within the tasklet handler to
> increase the likelihood of triggering the race condition.
>
> Fixes: 2f623aaf9f31 ("net: farsync: Fix kmemleak when rmmods farsync")
> Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
> ---
> drivers/net/wan/farsync.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
> index 5b01642ca44..6b2d1e63855 100644
> --- a/drivers/net/wan/farsync.c
> +++ b/drivers/net/wan/farsync.c
> @@ -2550,6 +2550,8 @@ fst_remove_one(struct pci_dev *pdev)
>
> fst_disable_intr(card);
> free_irq(card->irq, card);
> + tasklet_kill(&fst_tx_task);
> + tasklet_kill(&fst_int_task);
>
> iounmap(card->ctlmem);
> iounmap(card->mem);
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH net] net: wan: farsync: Fix use-after-free bugs caused by unfinished tasklets
2026-02-19 12:46 [PATCH net] net: wan: farsync: Fix use-after-free bugs caused by unfinished tasklets Duoming Zhou
2026-02-24 8:34 ` Jijie Shao
@ 2026-02-24 9:40 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 3+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-02-24 9:40 UTC (permalink / raw)
To: Duoming Zhou
Cc: netdev, linux-kernel, kevin.curtis, andrew+netdev, davem,
edumazet, kuba, pabeni
Hello:
This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Thu, 19 Feb 2026 20:46:37 +0800 you wrote:
> When the FarSync T-series card is being detached, the fst_card_info is
> deallocated in fst_remove_one(). However, the fst_tx_task or fst_int_task
> may still be running or pending, leading to use-after-free bugs when the
> already freed fst_card_info is accessed in fst_process_tx_work_q() or
> fst_process_int_work_q().
>
> A typical race condition is depicted below:
>
> [...]
Here is the summary with links:
- [net] net: wan: farsync: Fix use-after-free bugs caused by unfinished tasklets
https://git.kernel.org/netdev/net/c/bae8a5d2e759
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-02-24 9:39 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-19 12:46 [PATCH net] net: wan: farsync: Fix use-after-free bugs caused by unfinished tasklets Duoming Zhou
2026-02-24 8:34 ` Jijie Shao
2026-02-24 9:40 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox