mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] net/sched: hfsc: clear eligible node on reset
@ 2026-11-03 17:38 shaos
  2026-11-03 17:44 ` netdev-bot+sinfo
  0 siblings, 1 reply; 2+ messages in thread
From: shaos @ 2026-11-03 17:38 UTC (permalink / raw)
  To: Jamal Hadi Salim; +Cc: Jiri Pirko, netdev, linux-kernel

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


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-11-03 17:44 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-03 17:38 [PATCH] net/sched: hfsc: clear eligible node on reset shaos
2026-11-03 17:44 ` netdev-bot+sinfo

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®