Skip to content

Conversation

pvts-mat
Copy link
Contributor

[LTS 9.2]
CVE-2025-37890
VULN-68295

Problem

https://access.redhat.com/security/cve/CVE-2025-37890

A use-after-free vulnerability has been identified in the Linux kernel's HFSC (Hierarchical Fair Service Curve) queuing discipline when it is configured with NETEM (Network Emulation) as a child. This flaw can lead to a kernel panic or crash due to incorrect assumptions about the queue state. Exploitation of this vulnerability requires local access with CAP_NET_ADMIN privileges and control over the qdisc (queueing discipline) setup. A local attacker could leverage this flaw to achieve denial of service or escalate privileges. Given that it affects kernel memory structures, successful exploitation could result in memory corruption, data leaks, or arbitrary write capabilities, leading to a full kernel crash.

Applicability: yes

The patch relates to the sch_hfsc module, enabled with the NET_SCH_HFSC option. It's set to m in all configs of LTS 9.2:

$ grep 'NET_SCH_HFSC\b' configs/*.config

configs/kernel-aarch64-64k-debug-rhel.config:CONFIG_NET_SCH_HFSC=m
configs/kernel-aarch64-64k-rhel.config:CONFIG_NET_SCH_HFSC=m
configs/kernel-aarch64-debug-rhel.config:CONFIG_NET_SCH_HFSC=m
configs/kernel-aarch64-rhel.config:CONFIG_NET_SCH_HFSC=m
configs/kernel-ppc64le-debug-rhel.config:CONFIG_NET_SCH_HFSC=m
configs/kernel-ppc64le-rhel.config:CONFIG_NET_SCH_HFSC=m
configs/kernel-s390x-debug-rhel.config:CONFIG_NET_SCH_HFSC=m
configs/kernel-s390x-rhel.config:CONFIG_NET_SCH_HFSC=m
configs/kernel-s390x-zfcpdump-rhel.config:CONFIG_NET_SCH_HFSC=m
configs/kernel-x86_64-debug-rhel.config:CONFIG_NET_SCH_HFSC=m
configs/kernel-x86_64-rhel.config:CONFIG_NET_SCH_HFSC=m

The commit 37d9cf1 marked as introducing the bug is present in the ciqlts9_2's history. The mainline fix 141d343 wasn't backported. For the full picture please refer to the Appendix: Bug timeline section in #490.

Solution

The same situation as in #490, which see.

kABI check: passed

$ DEBUG=1 CVE=CVE-2025-37890 ./ninja.sh _kabi_checked__x86_64--test--ciqlts9_2-CVE-2025-37890

[0/1] Check ABI of kernel [ciqlts9_2-CVE-2025-37890]
++ uname -m
+ python3 /data/src/ctrliq-github/kernel-dist-git-el-9.2/SOURCES/check-kabi -k /data/src/ctrliq-github/kernel-dist-git-el-9.2/SOURCES/Module.kabi_x86_64 -s vms/x86_64--build--ciqlts9_2/build_files/kernel-src-tree-ciqlts9_2-CVE-2025-37890/Module.symvers
kABI check passed
+ touch state/kernels/ciqlts9_2-CVE-2025-37890/x86_64/kabi_checked

Boot test: passed

boot-test.log

Kselftests: passed relative

Coverage

Only the net-related tests were run. Arguably the most important are the tests in net/forwarding collection.

net/forwarding (except vxlan_bridge_1d_ipv6.sh, sch_tbf_prio.sh, sch_tbf_ets.sh, tc_actions.sh, tc_police.sh, sch_ets.sh, sch_tbf_root.sh, sch_red.sh), net/mptcp (except userspace_pm.sh, simult_flows.sh, mptcp_join.sh), net, netfilter (except nft_trans_stress.sh).

Reference

Batch 1:
kselftests–ciqlts9_2–run1.log
kselftests–ciqlts9_2–run2.log
kselftests–ciqlts9_2–run3.log
Batch 2:
kselftests–ciqlts9_2–run4.log

Patch

Batch 1:
kselftests–ciqlts9_2-CVE-2025-37890–run1.log
kselftests–ciqlts9_2-CVE-2025-37890–run2.log
kselftests–ciqlts9_2-CVE-2025-37890–run3.log
Batch 2:
kselftests–ciqlts9_2-CVE-2025-37890–run4.log

Comparison

There are some differences in the results but they're all for the tests marked before as unstable (see https://gitlab.conclusive.pl/devices/rocky-patching/-/blob/master/rocky.yml?ref_type=heads). They were just run by a mistake.

$ ktests.xsh diff -d kselftests*.log

Column    File
--------  ----------------------------------------------
Status0   kselftests--ciqlts9_2--run1.log
Status1   kselftests--ciqlts9_2--run2.log
Status2   kselftests--ciqlts9_2--run3.log
Status3   kselftests--ciqlts9_2--run4.log
Status4   kselftests--ciqlts9_2-CVE-2025-37890--run1.log
Status5   kselftests--ciqlts9_2-CVE-2025-37890--run2.log
Status6   kselftests--ciqlts9_2-CVE-2025-37890--run3.log
Status7   kselftests--ciqlts9_2-CVE-2025-37890--run4.log

TestCase            Status0  Status1  Status2  Status3  Status4  Status5  Status6  Status7  Summary
net:gro.sh          pass     fail     pass              pass     fail     pass              diff
net:txtimestamp.sh  fail     pass     pass              pass     pass     fail              diff

Specific tests: skipped

… qdisc

jira VULN-68295
cve CVE-2025-37890
commit-author Victor Nogueira <[email protected]>
commit 141d343

As described in Gerrard's report [1], we have a UAF case when an hfsc class
has a netem child qdisc. The crux of the issue is that hfsc is assuming
that checking for cl->qdisc->q.qlen == 0 guarantees that it hasn't inserted
the class in the vttree or eltree (which is not true for the netem
duplicate case).

This patch checks the n_active class variable to make sure that the code
won't insert the class in the vttree or eltree twice, catering for the
reentrant case.

[1] https://lore.kernel.org/netdev/CAHcdcOm+03OD2j6R0=YHKqmy=VgJ8xEOKuP6c7mSgnp-TEJJbw@mail.gmail.com/

Fixes: 37d9cf1 ("sched: Fix detection of empty queues in child qdiscs")
	Reported-by: Gerrard Tai <[email protected]>
	Acked-by: Jamal Hadi Salim <[email protected]>
	Signed-off-by: Victor Nogueira <[email protected]>
Link: https://patch.msgid.link/[email protected]
	Signed-off-by: Jakub Kicinski <[email protected]>
(cherry picked from commit 141d343)
	Signed-off-by: Marcin Wcisło <[email protected]>
jira VULN-68295
cve-bf CVE-2025-37890
commit-author Pedro Tammela <[email protected]>
commit ac9fe7d

Savino says:
    "We are writing to report that this recent patch
    (141d343) [1]
    can be bypassed, and a UAF can still occur when HFSC is utilized with
    NETEM.

    The patch only checks the cl->cl_nactive field to determine whether
    it is the first insertion or not [2], but this field is only
    incremented by init_vf [3].

    By using HFSC_RSC (which uses init_ed) [4], it is possible to bypass the
    check and insert the class twice in the eltree.
    Under normal conditions, this would lead to an infinite loop in
    hfsc_dequeue for the reasons we already explained in this report [5].

    However, if TBF is added as root qdisc and it is configured with a
    very low rate,
    it can be utilized to prevent packets from being dequeued.
    This behavior can be exploited to perform subsequent insertions in the
    HFSC eltree and cause a UAF."

To fix both the UAF and the infinite loop, with netem as an hfsc child,
check explicitly in hfsc_enqueue whether the class is already in the eltree
whenever the HFSC_RSC flag is set.

[1] https://web.git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=141d34391abbb315d68556b7c67ad97885407547
[2] https://elixir.bootlin.com/linux/v6.15-rc5/source/net/sched/sch_hfsc.c#L1572
[3] https://elixir.bootlin.com/linux/v6.15-rc5/source/net/sched/sch_hfsc.c#L677
[4] https://elixir.bootlin.com/linux/v6.15-rc5/source/net/sched/sch_hfsc.c#L1574
[5] https://lore.kernel.org/netdev/8DuRWwfqjoRDLDmBMlIfbrsZg9Gx50DHJc1ilxsEBNe2D6NMoigR_eIRIG0LOjMc3r10nUUZtArXx4oZBIdUfZQrwjcQhdinnMis_0G7VEk=@willsroot.io/T/#u

Fixes: 37d9cf1 ("sched: Fix detection of empty queues in child qdiscs")
	Reported-by: Savino Dicanosa <[email protected]>
	Reported-by: William Liu <[email protected]>
	Acked-by: Jamal Hadi Salim <[email protected]>
	Tested-by: Victor Nogueira <[email protected]>
	Signed-off-by: Pedro Tammela <[email protected]>
Link: https://patch.msgid.link/[email protected]
	Signed-off-by: Paolo Abeni <[email protected]>

(cherry picked from commit ac9fe7d)
	Signed-off-by: Marcin Wcisło <[email protected]>
Copy link
Collaborator

@PlaidCat PlaidCat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Copy link
Collaborator

@bmastbergen bmastbergen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥌

Copy link
Collaborator

@PlaidCat PlaidCat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@PlaidCat PlaidCat merged commit 22cdf91 into ctrliq:ciqlts9_2 Aug 15, 2025
2 of 3 checks passed
@PlaidCat
Copy link
Collaborator

Merged since our informative GHA is broken for Forked repos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants