Re: [PATCH net] net/sched: defer qdisc freeing after failed creation

From: Jamal Hadi Salim

Date: Wed Aug 19 2026 - 05:12:52 EST


On Mon, Aug 17, 2026 at 5:06 AM David Lee <david.lee@xxxxxxxxxxxxxxx> wrote:
>
> Hi Jakub,
>
> Apologies for the confusion. I've reattached the correct reproducer.
>

Thanks for reattaching the correct reproducer. I have run it and the
KASAN use-after-free in now matches the bug exactly. The earlier log
showed a different issue, please ensure logs match the bug and the
repro in the future to reduce review time. We run every test - and we
will vet your claim; so sending the wrong log consumes our time for no
good reason.

The fix itself is sound, but it requires a v2:
Per request from both Jakub and Sashiko: Inline qdisc_free() into
qdisc_free_cb() (or make it static) since your patch removes its last
external caller, so the standalone symbol is dead weight.
Attaching a C poc to the patch is not something i have seen; make it
separate. So mext steps: you are going to send 0/1 with the attached
poc and a good description of what changes you made since v1. Then 1/1
is the refactored patch.

Keep Fixes: 51ab2994c387 since the that's the commit that made clsact
bind a shared block before creation completes.

cheers,
jamal

> ======== 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.