Re: [PATCH net] net/sched: defer qdisc freeing after failed creation
From: David Lee
Date: Mon Aug 17 2026 - 05:06:21 EST
Hi Jakub,
Apologies for the confusion. I've reattached the correct reproducer.
======== Affected Versions =======
Runtime reproduction: Linux 7.2.0-rc3-kasan
Confirmed vulnerable revision:
f5098b6bae761e346ebcd9da7f95622c04733cff (Linux 7.2-rc5)
Latest inspected vulnerable revisions:
* 62cc90241548d5570ee68e01aaba6506964e9811 (Torvalds master)
* 9d8da8e0a9bce4a340af60dd0446bc7eb8d07587 (net main)
Introduced by:
51ab2994c387c80b45caf8b8067b3f3b97771d25
("net: sched: allow ingress and clsact qdiscs to share filter blocks")
https://github.com/torvalds/linux/commit/51ab2994c387c80b45caf8b8067b3f3b97771d25
Required Configs for the Vulnerability:
* CONFIG_NET_SCHED
* CONFIG_NET_SCH_INGRESS
* CONFIG_NET_CLS_ACT
Additional Configs used by the Proof-of-Concept:
* CONFIG_NET_CLS_BPF
* CONFIG_TUN
* CONFIG_USER_NS
* CONFIG_NET_NS
* CONFIG_KASAN
========== Reproduction ==========
Step 1: Build and boot a KASAN-enabled kernel with the configurations
listed above.
Step 2: Statically compile the attached `poc.c`:
~
gcc -static -O2 -Wall -Wextra -pthread -o poc poc.c
~
Step 3: Run `./poc` as a regular local user. The program creates an
owned user and network namespace, two TUN interfaces, and a populated
shared ingress block. It sends ingress traffic while repeatedly
requesting a `clsact` qdisc with the shared block and the invalid rate
estimator.
Step 4: Because this is a race, triggering time varies. The validated
run reported:
~
BUG: KASAN: slab-use-after-free in tc_run+0x5e3/0x620
Read of size 8 ... by task poc/...
Freed by task ...:
kfree
qdisc_free
qdisc_create
tc_modify_qdisc
~
The complete KASAN report is attached as `splash.txt`.
Best regards,
David
Apologies for the confusion. I've reattached the correct reproducer.
======== Affected Versions =======
Runtime reproduction: Linux 7.2.0-rc3-kasan
Confirmed vulnerable revision:
f5098b6bae761e346ebcd9da7f95622c04733cff (Linux 7.2-rc5)
Latest inspected vulnerable revisions:
* 62cc90241548d5570ee68e01aaba6506964e9811 (Torvalds master)
* 9d8da8e0a9bce4a340af60dd0446bc7eb8d07587 (net main)
Introduced by:
51ab2994c387c80b45caf8b8067b3f3b97771d25
("net: sched: allow ingress and clsact qdiscs to share filter blocks")
https://github.com/torvalds/linux/commit/51ab2994c387c80b45caf8b8067b3f3b97771d25
Required Configs for the Vulnerability:
* CONFIG_NET_SCHED
* CONFIG_NET_SCH_INGRESS
* CONFIG_NET_CLS_ACT
Additional Configs used by the Proof-of-Concept:
* CONFIG_NET_CLS_BPF
* CONFIG_TUN
* CONFIG_USER_NS
* CONFIG_NET_NS
* CONFIG_KASAN
========== Reproduction ==========
Step 1: Build and boot a KASAN-enabled kernel with the configurations
listed above.
Step 2: Statically compile the attached `poc.c`:
~
gcc -static -O2 -Wall -Wextra -pthread -o poc poc.c
~
Step 3: Run `./poc` as a regular local user. The program creates an
owned user and network namespace, two TUN interfaces, and a populated
shared ingress block. It sends ingress traffic while repeatedly
requesting a `clsact` qdisc with the shared block and the invalid rate
estimator.
Step 4: Because this is a race, triggering time varies. The validated
run reported:
~
BUG: KASAN: slab-use-after-free in tc_run+0x5e3/0x620
Read of size 8 ... by task poc/...
Freed by task ...:
kfree
qdisc_free
qdisc_create
tc_modify_qdisc
~
The complete KASAN report is attached as `splash.txt`.
Best regards,
David
On Wed, Aug 12, 2026 at 9:22 PM Jakub Kicinski <kuba@xxxxxxxxxx> wrote:
On Tue, 11 Aug 2026 00:58:27 +0900 David Lee wrote:
> [ 230.057740] ipip: IPv4 and MPLS over IPv4 tunneling driver
> [ 231.667279]
> ==================================================================
> [ 231.667738] BUG: KASAN: stack-out-of-bounds in
> __ip_options_echo+0xdf7/0x1860
I'm struggling to see how this is a repro for the qdisc lifecycle bug
In any case -- if the fix is really correct and there's some real repro
shared off list - I think you're deleting the last caller of
qdisc_free() so you should inline it into qdisc_free_cb()
So patch as is needs to be refactored. But please don't repost just
to refactor, we need a convincing repro first.
[ 232.894793] BUG: KASAN: slab-use-after-free in tc_run+0x5e3/0x620
[ 232.894793] Read of size 8 at addr ffff8881032c51e8 by task poc/1272
[ 232.894793]
[ 232.894793] CPU: 3 UID: 1000 PID: 1272 Comm: poc Not tainted 7.2.0-rc3-kasan #1 PREEMPT(lazy)
[ 232.894793] Hardware name: QEMU Ubuntu 26.04 PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1ubuntu1 04/01/2014
[ 232.894793] Call Trace:
[ 232.894793] <TASK>
[ 232.894793] dump_stack_lvl+0x5f/0x90
[ 232.894793] print_report+0x15b/0x4ec
[ 232.894793] ? __pfx__raw_spin_lock_irqsave+0x10/0x10
[ 232.894793] ? kasan_complete_mode_report_info+0x88/0x230
[ 232.894793] kasan_report+0xf2/0x130
[ 232.894793] ? tc_run+0x5e3/0x620
[ 232.894793] ? tc_run+0x5e3/0x620
[ 232.894793] __asan_report_load8_noabort+0x14/0x30
[ 232.894793] tc_run+0x5e3/0x620
[ 232.894793] ? __pfx_tc_run+0x10/0x10
[ 232.894793] __netif_receive_skb_core.constprop.0+0x9cc/0x31e0
[ 232.894793] ? __pfx___skb_flow_dissect+0x10/0x10
[ 232.894793] ? __pfx___netif_receive_skb_core.constprop.0+0x10/0x10
[ 232.894793] ? lapic_next_event+0x15/0x30
[ 232.894793] ? clockevents_program_event+0x2bd/0x750
[ 232.894793] ? ktime_get+0x100/0x190
[ 232.894793] ? __alloc_skb+0x34c/0xa10
[ 232.894793] ? lapic_next_event+0x15/0x30
[ 232.894793] ? __pfx_clockevents_program_event+0x10/0x10
[ 232.894793] ? __kasan_check_write+0x14/0x30
[ 232.894793] ? _raw_spin_lock+0x82/0xf0
[ 232.894793] __netif_receive_skb_one_core+0xa5/0x1d0
[ 232.894793] ? tick_program_event+0x69/0x130
[ 232.894793] ? __pfx___netif_receive_skb_one_core+0x10/0x10
[ 232.894793] ? __hrtimer_rearm_deferred+0x18a/0x520
[ 232.894793] ? sysvec_apic_timer_interrupt+0x54/0xd0
[ 232.894793] ? irqentry_exit+0x1cd/0x7b0
[ 232.894793] __netif_receive_skb+0x1c/0x160
[ 232.894793] netif_receive_skb+0x2f3/0x420
[ 232.894793] ? asm_sysvec_apic_timer_interrupt+0x1b/0x20
[ 232.894793] ? __pfx_netif_receive_skb+0x10/0x10
[ 232.894793] tun_get_user+0x2208/0x3c40
[ 232.894793] ? aa_file_perm+0x544/0xf20
[ 232.894793] ? __pfx_tun_get_user+0x10/0x10
[ 232.894793] ? rcu_sched_clock_irq+0xf08/0x2310
[ 232.894793] ? apparmor_file_permission+0x14d/0x500
[ 232.894793] ? __pfx_apparmor_file_permission+0x10/0x10
[ 232.894793] ? update_cfs_group+0x218/0x380
[ 232.894793] tun_chr_write_iter+0x176/0x2a0
[ 232.894793] ? tun_chr_write_iter+0x176/0x2a0
[ 232.894793] ? __pfx_run_posix_cpu_timers+0x10/0x10
[ 232.894793] vfs_write+0x580/0xf70
[ 232.894793] ? perf_event_task_tick+0x92/0x1d0
[ 232.894793] ? __pfx_vfs_write+0x10/0x10
[ 232.894793] ? __kasan_check_write+0x14/0x30
[ 232.894793] ? __kasan_check_write+0x14/0x30
[ 232.894793] ? fdget_pos+0x420/0x600
[ 232.894793] ksys_write+0x104/0x240
[ 232.894793] ? __pfx_ksys_write+0x10/0x10
[ 232.894793] ? lapic_next_event+0x15/0x30
[ 232.894793] ? clockevents_program_event+0x2bd/0x750
[ 232.894793] __x64_sys_write+0x72/0xd0
[ 232.894793] ? ktime_get_update_offsets_now+0x1d5/0x400
[ 232.894793] x64_sys_call+0x22f/0x2390
[ 232.894793] do_syscall_64+0xdd/0x640
[ 232.894793] ? __kasan_check_write+0x14/0x30
[ 232.894793] ? _raw_spin_lock+0x82/0xf0
[ 232.894793] ? __pfx__raw_spin_lock+0x10/0x10
[ 232.894793] ? tick_program_event+0x69/0x130
[ 232.894793] ? __kasan_check_read+0x11/0x20
[ 232.894793] ? fpregs_assert_state_consistent+0x5c/0x100
[ 232.894793] ? irqentry_exit+0x3f/0x7b0
[ 232.894793] ? __irq_exit_rcu+0x45/0x250
[ 232.894793] ? __sysvec_apic_timer_interrupt+0x91/0x320
[ 232.894793] ? do_syscall_64+0x94/0x640
[ 232.894793] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 232.894793] RIP: 0033:0x440692
[ 232.910990] Code: 08 0f 85 f1 de 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 00 f3 0f 1e fa 55 48 89 e5
[ 232.911028] RSP: 002b:000070c4801be188 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[ 232.911028] RAX: ffffffffffffffda RBX: 00007ffdcdd87380 RCX: 0000000000440692
[ 232.911028] RDX: 0000000000000040 RSI: 00000000004a8500 RDI: 0000000000000004
[ 232.911028] RBP: 000070c4801be1b0 R08: 0000000000000000 R09: 0000000000000000
[ 232.911028] R10: 0000000000000000 R11: 0000000000000246 R12: 000070c4801be6c0
[ 232.911028] R13: 00007ffdcdd87170 R14: 000070c4801bece4 R15: 00007ffdcdd87267
[ 232.911028] </TASK>
[ 232.911028]
[ 232.934520] Allocated by task 1267 on cpu 0 at 232.847363s:
[ 232.934520] kasan_save_stack+0x3a/0x70
[ 232.934520] kasan_save_track+0x18/0x70
[ 232.934520] kasan_save_alloc_info+0x39/0x60
[ 232.934520] __kasan_kmalloc+0xa9/0xd0
[ 232.934520] __kmalloc_node_noprof+0x208/0x630
[ 232.934520] qdisc_alloc+0xba/0x7a0
[ 232.934520] qdisc_create+0x6e/0xc80
[ 232.934520] tc_modify_qdisc+0xab5/0x1ff0
[ 232.934520] rtnetlink_rcv_msg+0x34f/0xb00
[ 232.934520] netlink_rcv_skb+0x147/0x400
[ 232.934520] rtnetlink_rcv+0x15/0x30
[ 232.934520] netlink_unicast+0x796/0xb30
[ 232.934520] netlink_sendmsg+0x770/0xc70
[ 232.934520] ____sys_sendmsg+0x95d/0xc50
[ 232.934520] ___sys_sendmsg+0x101/0x1a0
[ 232.934520] __sys_sendmsg+0x127/0x1e0
[ 232.934520] __x64_sys_sendmsg+0x77/0xd0
[ 232.934520] x64_sys_call+0x20d2/0x2390
[ 232.934520] do_syscall_64+0xdd/0x640
[ 232.934520] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 232.934520]
[ 232.934520] Freed by task 1267 on cpu 0 at 232.854692s:
[ 232.934520] kasan_save_stack+0x3a/0x70
[ 232.934520] kasan_save_track+0x18/0x70
[ 232.934520] kasan_save_free_info+0x3b/0x70
[ 232.934520] __kasan_slab_free+0x7a/0xb0
[ 232.934520] kfree+0x1bd/0x510
[ 232.934520] qdisc_free+0x9c/0xd0
[ 232.934520] qdisc_create+0x5b0/0xc80
[ 232.934520] tc_modify_qdisc+0xab5/0x1ff0
[ 232.934520] rtnetlink_rcv_msg+0x34f/0xb00
[ 232.934520] netlink_rcv_skb+0x147/0x400
[ 232.934520] rtnetlink_rcv+0x15/0x30
[ 232.934520] netlink_unicast+0x796/0xb30
[ 232.934520] netlink_sendmsg+0x770/0xc70
[ 232.934520] ____sys_sendmsg+0x95d/0xc50
[ 232.934520] ___sys_sendmsg+0x101/0x1a0
[ 232.934520] __sys_sendmsg+0x127/0x1e0
[ 232.934520] __x64_sys_sendmsg+0x77/0xd0
[ 232.934520] x64_sys_call+0x20d2/0x2390
[ 232.934520] do_syscall_64+0xdd/0x640
[ 232.934520] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 232.934520]
[ 232.934520] The buggy address belongs to the object at ffff8881032c5000
[ 232.934520] which belongs to the cache kmalloc-part-02-1k of size 1024
[ 232.934520] The buggy address is located 488 bytes inside of
[ 232.934520] freed 1024-byte region [ffff8881032c5000, ffff8881032c5400)
[ 232.934520]
[ 232.934520] The buggy address belongs to the physical page:
[ 232.934520] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff8881032c6800 pfn:0x1032c0
[ 232.934520] head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
[ 232.934520] flags: 0x17ffffc0000240(workingset|head|node=0|zone=2|lastcpupid=0x1fffff)
[ 232.934520] page_type: f5(slab)
[ 232.934520] raw: 0017ffffc0000240 ffff888100048f00 ffff888100041290 ffffea0004071610
[ 232.934520] raw: ffff8881032c6800 000000080010000e 00000000f5000000 0000000000000000
[ 232.934520] head: 0017ffffc0000240 ffff888100048f00 ffff888100041290 ffffea0004071610
[ 232.934520] head: ffff8881032c6800 000000080010000e 00000000f5000000 0000000000000000
[ 232.934520] head: 0017ffffc0000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff
[ 232.934520] head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008
[ 232.934520] page dumped because: kasan: bad access detected
[ 232.934520]
[ 232.934520] Memory state around the buggy address:
[ 232.934520] ffff8881032c5080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 232.934520] ffff8881032c5100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 232.934520] >ffff8881032c5180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 232.934520] ^
[ 232.934520] ffff8881032c5200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 232.934520] ffff8881032c5280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[ 232.934520] ==================================================================
[ 233.001266] Disabling lock debugging due to kernel taint
Attachment:
poc.c
Description: Binary data