mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: shaos <shawnq1@163.com>
To: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Jiri Pirko <jiri@resnulli.us>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] net/sched: hfsc: clear eligible node on reset
Date: Wed, 4 Nov 2026 01:38:44 +0800 (CST)	[thread overview]
Message-ID: <6AEA1C23.11E1A6.00008@m16.mail.163.com> (raw)

Hello,

hfsc_reset_class() clears the realtime class counters but leaves its
el_node marked as linked.  hfsc_reset_qdisc() then discards the
scheduler-wide eligible tree by assigning RB_ROOT.  After a link
reset with an RSC class backlogged, the next packet sees the stale
non-empty el_node, skips init_ed(), and leaves the class absent from the
new eligible tree.  HFSC then retains the packet in its child qdisc
without a dequeue event or watchdog recovery.

Two fresh QEMU runs reproduced a permanently queued packet after
link down/up.  An FSC-only class, a drained-queue reset, and a no-reset
control transmitted normally.  A kernel with the patch below reported
RESULT=NOT_STUCK and transmitted the packet.  This requires control of
the HFSC qdisc and is a scheduler liveness/correctness defect; no memory
corruption or privilege escalation was observed.

HEAD commit:    c03c1a14507dfaf8b856c2608f9ac216021fc222
Git tree:       30fd2ef82912c26cf3a58ad0ba6afc375fa851ac
Source version: Linux 7.3
Compiler:       gcc 11.4.0, GNU ld 2.38

The console logs, full kernel config, packet sender, and QEMU/initramfs
harness are available from one fixed-revision Gist:

Console output:
https://gist.githubusercontent.com/shaos26/d7ec57d3a631368bd50ad0182ce9c268/raw/6344f32527074498da61f02b58068539859b388e/console-output.txt
Kernel config:
https://gist.githubusercontent.com/shaos26/d7ec57d3a631368bd50ad0182ce9c268/raw/6344f32527074498da61f02b58068539859b388e/kernel-config.txt
PoC source:
https://gist.githubusercontent.com/shaos26/d7ec57d3a631368bd50ad0182ce9c268/raw/6344f32527074498da61f02b58068539859b388e/poc.c
Harness: hfsc_reset_harness.sh
https://gist.githubusercontent.com/shaos26/d7ec57d3a631368bd50ad0182ce9c268/raw/6344f32527074498da61f02b58068539859b388e/hfsc_reset_harness.sh
Harness: init.sh
https://gist.githubusercontent.com/shaos26/d7ec57d3a631368bd50ad0182ce9c268/raw/6344f32527074498da61f02b58068539859b388e/init.sh
Harness: mkinitramfs.sh
https://gist.githubusercontent.com/shaos26/d7ec57d3a631368bd50ad0182ce9c268/raw/6344f32527074498da61f02b58068539859b388e/mkinitramfs.sh
Harness: run-qemu.sh
https://gist.githubusercontent.com/shaos26/d7ec57d3a631368bd50ad0182ce9c268/raw/6344f32527074498da61f02b58068539859b388e/run-qemu.sh

Clone the Gist and build the vulnerable kernel and initramfs.  The
kernel source is the HEAD commit above; use the attached full config.
The host needs gcc, fakeroot, cpio, gzip, BusyBox, iproute2, and QEMU:

    git clone \
      https://gist.github.com/shaos26/d7ec57d3a631368bd50ad0182ce9c268.git \
      hfsc-repro
    cd hfsc-repro
    TMP=/tmp/hfsc-repro-build
    mkdir -p "$TMP/rootfs"
    git clone \
      https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git \
      linux
    git -C linux checkout c03c1a14507dfaf8b856c2608f9ac216021fc222
    cp kernel-config.txt linux/.config
    make -C linux olddefconfig
    make -C linux -j"$(nproc)" bzImage
    mkdir -p poc
    mv hfsc_reset_harness.sh init.sh mkinitramfs.sh run-qemu.sh poc/
    cc -O2 -static -Wall -Wextra -Werror -o poc/hfsc_probe poc.c
    fakeroot -- sh poc/mkinitramfs.sh "$TMP/rootfs" "$TMP/initramfs.cpio.gz"

Run the positive and close controls on fresh QEMU boots:

    KERNEL="$PWD/linux/arch/x86/boot/bzImage" \
    INITRD="$TMP/initramfs.cpio.gz" OUT="$TMP/rt-reset.log" \
    sh poc/run-qemu.sh rt-reset
    KERNEL="$PWD/linux/arch/x86/boot/bzImage" \
    INITRD="$TMP/initramfs.cpio.gz" OUT="$TMP/ls-reset.log" \
    sh poc/run-qemu.sh ls-reset
    KERNEL="$PWD/linux/arch/x86/boot/bzImage" \
    INITRD="$TMP/initramfs.cpio.gz" OUT="$TMP/rt-drained-reset.log" \
    sh poc/run-qemu.sh rt-drained-reset
    KERNEL="$PWD/linux/arch/x86/boot/bzImage" \
    INITRD="$TMP/initramfs.cpio.gz" OUT="$TMP/rt-noreset.log" \
    sh poc/run-qemu.sh rt-noreset

The positive prints RESULT=STUCK.  Controls print RESULT=CONTROL_PASS.
For the fixed-kernel mechanism control, rebuild from the patched source;
rt-reset then prints RESULT=NOT_STUCK.  The guest configures a qdisc and
sends AF_PACKET frames, so it runs as root in QEMU.  A direct trigger
requires CAP_NET_ADMIN and CAP_NET_RAW.

The eligible-node marker must be cleared when the class scheduler state
is reset:

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: shaos <shawnq1@163.com>
---
 net/sched/sch_hfsc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1488,6 +1488,7 @@ static void hfsc_reset_class(struct hfsc_class *cl)
 	cl->cl_myf          = 0;
 	cl->cl_cfmin        = 0;
 	cl->cl_nactive      = 0;
+	RB_CLEAR_NODE(&cl->el_node);
 
 	cl->vt_tree = RB_ROOT;
 	cl->cf_tree = RB_ROOT;
-- 
2.34.1


             reply	other threads:[~2026-11-03 17:38 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-03 17:38 shaos [this message]
2026-11-03 17:44 ` netdev-bot+sinfo

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=6AEA1C23.11E1A6.00008@m16.mail.163.com \
    --to=shawnq1@163.com \
    --cc=jhs@mojatatu.com \
    --cc=jiri@resnulli.us \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®