Skip to content

[LTS 8.8] CVE-2023-4623, VULN-6709 #137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 21, 2025

Conversation

pvts-mat
Copy link
Contributor

[LTS 8.8]
CVE-2023-4623
VULN-6709

Problem

https://www.cve.org/CVERecord?id=CVE-2023-4623

A use-after-free vulnerability in the Linux kernel's net/sched: sch_hfsc (HFSC qdisc traffic control) component can be exploited to achieve local privilege escalation. If a class with a link-sharing curve (i.e. with the HFSC_FSC flag set) has a parent without a link-sharing curve, then init_vf() will call vttree_insert() on the parent, but vttree_remove() will be skipped in update_vf(). This leaves a dangling pointer that can cause a use-after-free.

Analysis and solution

A single commit was identified as a fix for this issue: b3d26c5702c7d6c45456326e56d2ccf3f103e60f net/sched: sch_hfsc: Ensure inner classes have fsc curve.

The solution consisted of rejecting the addition of a class with a link-sharing curve to the class without it (see Specific tests for details):

[root@ciqlts8_8 pvts]# (
    tc qdisc add dev lo root handle 1: hfsc default 10
    tc class add dev lo parent 1: classid 1:1 hfsc rt m2 100kbps
    tc class add dev lo parent 1:1 classid 1:10 hfsc ls m2 50kbps
    echo $?
)

Error: Invalid parent - parent class must have FSC.
2

The fix introduced a problem with existing network setup scripts for some users https://lore.kernel.org/all/[email protected]/:

I upgraded from 6.1.38 to 6.1.55 this morning and it broke my traffic shaping script, leaving me with a non-functional uplink on a remote router.

It was decided to fix the problem without breaking backwards compatibility https://lore.kernel.org/all/[email protected]/:

Setting 'rt' as a parent is incorrect and the man page is explicit about
it as it doesn't make sense 'qdisc wise'. Being able to set it has
always been wrong unfortunately…

Sure but unfortunately "we don't break backward compat" means
we can't really argue. It will take us more time to debate this
than to fix it (assuming we understand the initial problem).

Frankly one can even argue whether "exploitable by root / userns"
is more important than single user's init scripts breaking.
The "security" issues for root are dime a dozen.

The solution was to change the erroneous qdisc hierarchy to a correct one when the possible UAF condition was detected https://lore.kernel.org/all/[email protected]/:

As reported [1] disallowing 'rt' inner curves breaks already existing
scripts. Even though it doesn't make sense 'qdisc wise' users have been
relying on this behaviour since the qdisc inception.

We need users to update the scripts/applications to use 'sc' or 'ls'
as a inner curve instead of 'rt', but also avoid the UAF found by
Budimir, which was present since the qdisc inception.

The fix of the fix is given in the commit a13b67c9a015c4e21601ef9aa4ec9c5d972df1b4 net/sched: sch_hfsc: upgrade 'rt' to 'sc' when it becomes a inner curve

While the changes could be squashed into a single commit it was decided to retain the sequence of two commits for more straightforward LTS 8.8 - mainline patches correspondence.

The same solution was used already in other "version 8" branches centos8, fips-8-complaint/4.18.0-553.16.1, fips-8/4.18.0-553.16.1, rocky8_10, sig-cloud-8/4.18.0-553.22.1.el8_10, sig-cloud-8/4.18.0-553.33.1.el8_10, sig-cloud-8/4.18.0-553.36.1.el8_10:

git --no-pager log --decorate  --format="%h %cd %d %s" --date=short -n 2 ae71642ce

ae71642ce 2024-09-11  net/sched: sch_hfsc: upgrade 'rt' to 'sc' when it becomes a inner curve
1a61f0a5d 2024-09-11  net/sched: sch_hfsc: Ensure inner classes have fsc curve

kABI check: passed

CVE=CVE-2023-4623 ./ninja.sh _kabi_checked_ciqlts8_8-CVE-2023-4623

ninja: Entering directory `/data/build/rocky-patching'
[0/2] Create worktree for branch 'el-8.8': '/data/src/ctrliq-github/kernel-dist-git-el-8.8' (main repo: '/data/src/ctrliq-github/kernel-dist-git')
+ rm -rf /data/src/ctrliq-github/kernel-dist-git-el-8.8
+ git -C /data/src/ctrliq-github/kernel-dist-git worktree prune
+ git -C /data/src/ctrliq-github/kernel-dist-git worktree add /data/src/ctrliq-github/kernel-dist-git-el-8.8 el-8.8
Preparing worktree (checking out 'el-8.8')
HEAD is now at 3120f78 import kernel-4.18.0-477.27.1.el8_8.88ciq_lts.2.1
[1/2] Check ABI of kernel [ciqlts8_8-CVE-2023-4623]	_kabi_checked_ciqlts8_8-CVE-2023-4623
+ python3 /data/src/ctrliq-github/kernel-dist-git-el-8.8/SOURCES/check-kabi -k /data/src/ctrliq-github/kernel-dist-git-el-8.8/SOURCES/Module.kabi_x86_64 -s vms/build-ciqlts8_8/build_files/kernel-src-tree-ciqlts8_8-CVE-2023-4623/Module.symvers
kABI check passed
+ touch state/kernels/ciqlts8_8-CVE-2023-4623/kabi_checked

Boot test: passed

Refer to Specific tests for implicit boot test passing.

Kselftests

Methodology

A mix of kernel-selftests-internal and source-compiled tests were used:

  • kernel-selftests-internal: bpf tests, except:
    • bpf:test_kmod.sh: takes very long time to finish and always fails anyway,
    • bpf:test_progs: unstable, can crash the machine,
    • bpf:test_progs-no_alu32: unstable, can crash the machine.
  • source-compiled: all the rest.

Coverage (including tests skipped during execution)

android, bpf, breakpoints, capabilities, cgroup, core, cpu-hotplug, cpufreq, drivers/net/bonding, drivers/net/team, efivarfs, exec, filesystems, firmware, fpu, ftrace, futex, gpio, intel_pstate, ipc, kcmp, kvm, lib, livepatch, membarrier, memfd, memory-hotplug, mount, mqueue, net, net/forwarding, net/mptcp, netfilter, nsfs, proc, pstore, ptrace, rseq, rtc, sgx, sigaltstack, size, splice, static_keys, sync, sysctl, tc-testing, tdx, timens, timers, tpm2, user, vm, x86, zram

Reference ciqlts8_8 (6bfcdd41f5877d7326b3c3bf848f8f9c0c93465c)

Two test runs were conducted on the reference kernel.
kselftests–mixed–ciqlts8_8–run1.log
kselftests–mixed–ciqlts8_8–run2.log

Patch ciqlts8_8-CVE-2023-4623 (e35af37ed7bf4462a9c57844fcce23b19862df90)

Two test runs were conducted on the patched kernel.
kselftests–mixed–ciqlts8_8-CVE-2023-4623–run1.log
kselftests–mixed–ciqlts8_8-CVE-2023-4623–run2.log

Comparison

ktests.xsh  table --where "Summary = 'diff'"  kselftests*.log

Column    File
--------  ----------------------------------------------------
Status0   kselftests--mixed--ciqlts8_8--run1.log
Status1   kselftests--mixed--ciqlts8_8--run2.log
Status2   kselftests--mixed--ciqlts8_8-CVE-2023-4623--run1.log
Status3   kselftests--mixed--ciqlts8_8-CVE-2023-4623--run2.log

TestCase                   Status0  Status1  Status2  Status3  Summary
net/mptcp:simult_flows.sh  pass     fail     pass     fail     diff
net:gro.sh                 fail     pass     pass     pass     diff
net:ip_defrag.sh           fail     pass     pass     pass     diff
net:reuseport_addr_any.sh  pass     fail     fail     fail     diff

Tests net/mptcp:simult_flows.sh, net:gro.sh have already shown inconsistent behavior before https://docs.google.com/spreadsheets/d/1tUwJ2rV57cYZXh7momPtraSjZcHDjMYHLeHA3DYWrUU/edit?pli=1&gid=0#gid=0&range=F:G

The net:ip_defrag.sh, net:reuseport_addr_any.sh tests showed inconsistent behavior in the reference tests set itself. Added to the list of "flappy" tests for the ciqlts8_8 platform.

Specific tests: passed

The potential UAF condition was found to be reproducible with the following tc commands sequence:

tc qdisc add dev lo root handle 1: hfsc default 10
# Inner hfsc class constructed with 'rt' - realtime service
tc class add dev lo parent 1: classid 1:1 hfsc rt m2 100kbps
# Leaf hfsc class constructed with 'ls' - linksharing service
tc class add dev lo parent 1:1 classid 1:10 hfsc ls m2 50kbps

The "100kbps", "50kbps" parts are arbitrary. What's important is the use of rt for the inner class and ls for the leaf class. While the exact UAF was not obtained the commands helped confirm the efficacy of the patch.

Reference

The incorrect qdisc hierarchy can be created without any guardrails.

[root@ciqlts8_8 pvts]# (
    tc qdisc add dev lo root handle 1: hfsc default 10
    tc class add dev lo parent 1: classid 1:1 hfsc rt m2 100kbps
    tc class add dev lo parent 1:1 classid 1:10 hfsc ls m2 50kbps
    echo $?
)
0
[root@ciqlts8_8 pvts]# tc -g class show dev lo
tc -g  class show dev lo
+---(1:) hfsc 
     +---(1:1) hfsc rt m1 0bit d 0us m2 800Kbit 
          +---(1:10) hfsc ls m1 0bit d 0us m2 400Kbit 

Full logs:
fix-replicate–ciqlts8_8.log

Patch

Creating the incorrect qdisc hierarchy raises a warning, but succeeds. Notice the type of inner class being sc instead of rt as shown by tc -g class show dev lo command.

[root@ciqlts8_8 pvts]# (
    tc qdisc add dev lo root handle 1: hfsc default 10
    tc class add dev lo parent 1: classid 1:1 hfsc rt m2 100kbps
    tc class add dev lo parent 1:1 classid 1:10 hfsc ls m2 50kbps
    echo $?
)
Warning: Forced curve change on parent 'rt' to 'sc'.
0
[root@ciqlts8_8 pvts]# tc -g  class show dev lo
tc -g  class show dev lo
+---(1:) hfsc 
     +---(1:1) hfsc sc m1 0bit d 0us m2 800Kbit 
          +---(1:10) hfsc ls m1 0bit d 0us m2 400Kbit 

Full logs:
fix-replicate–ciqlts8_8-CVE-2023-4623–1.log

jira VULN-6709
cve CVE-2023-4623
commit-author Budimir Markovic <[email protected]>
commit b3d26c5

HFSC assumes that inner classes have an fsc curve, but it is currently
possible for classes without an fsc curve to become parents. This leads
to bugs including a use-after-free.

Don't allow non-root classes without HFSC_FSC to become parents.

Fixes: 1da177e ("Linux-2.6.12-rc2")
	Reported-by: Budimir Markovic <[email protected]>
	Signed-off-by: Budimir Markovic <[email protected]>
	Acked-by: Jamal Hadi Salim <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
	Signed-off-by: Jakub Kicinski <[email protected]>
(cherry picked from commit b3d26c5)
	Signed-off-by: Marcin Wcisło <[email protected]>
jira VULN-6709
cve CVE-2023-4623
commit-author Pedro Tammela <[email protected]>
commit a13b67c

Christian Theune says:
   I upgraded from 6.1.38 to 6.1.55 this morning and it broke my traffic shaping script,
   leaving me with a non-functional uplink on a remote router.

A 'rt' curve cannot be used as a inner curve (parent class), but we were
allowing such configurations since the qdisc was introduced. Such
configurations would trigger a UAF as Budimir explains:
   The parent will have vttree_insert() called on it in init_vf(),
   but will not have vttree_remove() called on it in update_vf()
   because it does not have the HFSC_FSC flag set.

The qdisc always assumes that inner classes have the HFSC_FSC flag set.
This is by design as it doesn't make sense 'qdisc wise' for an 'rt'
curve to be an inner curve.

Budimir's original patch disallows users to add classes with a 'rt'
parent, but this is too strict as it breaks users that have been using
'rt' as a inner class. Another approach, taken by this patch, is to
upgrade the inner 'rt' into a 'sc', warning the user in the process.
It avoids the UAF reported by Budimir while also being more permissive
to bad scripts/users/code using 'rt' as a inner class.

Users checking the `tc class ls [...]` or `tc class get [...]` dumps would
observe the curve change and are potentially breaking with this change.

v1->v2: https://lore.kernel.org/all/[email protected]/
- Correct 'Fixes' tag and merge with revert (Jakub)

	Cc: Christian Theune <[email protected]>
	Cc: Budimir Markovic <[email protected]>
Fixes: b3d26c5 ("net/sched: sch_hfsc: Ensure inner classes have fsc curve")
	Signed-off-by: Pedro Tammela <[email protected]>
	Acked-by: Jamal Hadi Salim <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
	Signed-off-by: Jakub Kicinski <[email protected]>
(cherry picked from commit a13b67c)
	Signed-off-by: Marcin Wcisło <[email protected]>
Copy link

@gvrose8192 gvrose8192 left a comment

Choose a reason for hiding this comment

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

As usual, a very well documented and structured PR. Thanks!

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.

🥌

@gvrose8192
Copy link

Checks passed - approved - merging.

@gvrose8192 gvrose8192 merged commit 325c80b into ctrliq:ciqlts8_8 Feb 21, 2025
2 checks passed
PlaidCat added a commit that referenced this pull request May 27, 2025
jira NONE_AUTOMATION
Rebuild_History Non-Buildable kernel-rt-4.18.0-348.20.1.rt7.150.el8_5
commit-author Mike Kravetz <[email protected]>
commit 79aa925

Michal Privoznik was using "free page reporting" in QEMU/virtio-balloon
with hugetlbfs and hit the warning below.  QEMU with free page hinting
uses fallocate(FALLOC_FL_PUNCH_HOLE) to discard pages that are reported
as free by a VM.  The reporting granularity is in pageblock granularity.
So when the guest reports 2M chunks, we fallocate(FALLOC_FL_PUNCH_HOLE)
one huge page in QEMU.

  WARNING: CPU: 7 PID: 6636 at mm/page_counter.c:57 page_counter_uncharge+0x4b/0x50
  Modules linked in: ...
  CPU: 7 PID: 6636 Comm: qemu-system-x86 Not tainted 5.9.0 #137
  Hardware name: Gigabyte Technology Co., Ltd. X570 AORUS PRO/X570 AORUS PRO, BIOS F21 07/31/2020
  RIP: 0010:page_counter_uncharge+0x4b/0x50
  ...
  Call Trace:
    hugetlb_cgroup_uncharge_file_region+0x4b/0x80
    region_del+0x1d3/0x300
    hugetlb_unreserve_pages+0x39/0xb0
    remove_inode_hugepages+0x1a8/0x3d0
    hugetlbfs_fallocate+0x3c4/0x5c0
    vfs_fallocate+0x146/0x290
    __x64_sys_fallocate+0x3e/0x70
    do_syscall_64+0x33/0x40
    entry_SYSCALL_64_after_hwframe+0x44/0xa9

Investigation of the issue uncovered bugs in hugetlb cgroup reservation
accounting.  This patch addresses the found issues.

Fixes: 075a61d ("hugetlb_cgroup: add accounting for shared mappings")
	Reported-by: Michal Privoznik <[email protected]>
Co-developed-by: David Hildenbrand <[email protected]>
	Signed-off-by: David Hildenbrand <[email protected]>
	Signed-off-by: Mike Kravetz <[email protected]>
	Signed-off-by: Andrew Morton <[email protected]>
	Tested-by: Michal Privoznik <[email protected]>
	Reviewed-by: Mina Almasry <[email protected]>
	Acked-by: Michael S. Tsirkin <[email protected]>
	Cc: <[email protected]>
	Cc: David Hildenbrand <[email protected]>
	Cc: Michal Hocko <[email protected]>
	Cc: Muchun Song <[email protected]>
	Cc: "Aneesh Kumar K . V" <[email protected]>
	Cc: Tejun Heo <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
	Signed-off-by: Linus Torvalds <[email protected]>
(cherry picked from commit 79aa925)
	Signed-off-by: Jonathan Maple <[email protected]>
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