Skip to content

[LTS 9.2] CVE-2023-4206, CVE-2023-4207, CVE-2023-4208 #158

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
Mar 13, 2025

Conversation

pvts-mat
Copy link
Contributor

@pvts-mat pvts-mat commented Mar 8, 2025

[LTS 9.2]
CVE-2023-4206 VULN-6649
CVE-2023-4207 VULN-6656
CVE-2023-4208 VULN-6663

Problem

The PR addresses a series of related CVEs, which were once listed under a single CVE-2023-4128. From https://lore.kernel.org/netdev/[email protected]/:

Three classifiers (cls_fw, cls_u32 and cls_route) always copy
tcf_result struct into the new instance of the filter on update.

This causes a problem when updating a filter bound to a class,
as tcf_unbind_filter() is always called on the old instance in the
success path, decreasing filter_cnt of the still referenced class
and allowing it to be deleted, leading to a use-after-free.

This patch set fixes this issue in all affected classifiers by no longer
copying the tcf_result struct from the old filter.

Each CVE is related to a different classifier:

CVE File Option
CVE-2023-4206 net/sched/cls_route.c CONFIG_NET_CLS_ROUTE4
CVE-2023-4207 net/sched/cls_fw.c CONFIG_NET_CLS_FW
CVE-2023-4208 net/sched/cls_u32.c CONFIG_NET_CLS_U32

Analysis and solution

Official fixes

The official fixes for each of the vulnerabilities are as follows:

CVE Mainline fix Backport to 5.15 (closest to 5.14 of Rocky LTS 9.2) Relation to mainline fix Applicable to LTS 9.2
CVE-2023-4206 b80b829 79c3d81c9ad140957b081c91908d7e2964dc603f Same No
CVE-2023-4207 76e42ae 9edf7955025a602ab6bcc94d923c436e160a10e3 Same Yes
CVE-2023-4208 3044b16 262430dfc618509246e07acd26211cb4cca79ecc Same Yes

Applicability

The CVE-2023-4206 is not applicable to the LTS 9.2 from the configuration standpoint, as the route4 classifier is disabled by default. Other CVEs are applicable.

grep -e '\(CONFIG_NET_SCHED\|CONFIG_NET_CLS\|CONFIG_NET_CLS_ROUTE4\|CONFIG_NET_CLS_FW\|CONFIG_NET_CLS_U32\)\b' configs/kernel-5.14.0-x86_64.config

CONFIG_NET_SCHED=y
CONFIG_NET_CLS=y
# CONFIG_NET_CLS_ROUTE4 is not set
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m

Analysis

For the discussion of the validity of a fix based on simply ignoring a certain field while copying a data structure where the actual copy may be expected see analysis for LTS 8.6 RT Pull Request - it was not repeated for the LTS 9.2 version. (Note that the doubts raised there about keeping tcindex filter don't apply to this version as this filter is disabled in LTS 9.2 configuration.)

kABI check

CVE=CVE-2023-4206.4207.4208 ./ninja.sh  _kabi_checked_ciqlts9_2-CVE-2023-4206.4207.4208

ninja: Entering directory `/data/build/rocky-patching'
[0/1] Check ABI of kernel [ciqlts9_2-CVE-2023-4206.4207.4208]
+ 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/build-ciqlts9_2/build_files/kernel-src-tree-ciqlts9_2-CVE-2023-4206.4207.4208/Module.symvers
kABI check passed
+ touch state/kernels/ciqlts9_2-CVE-2023-4206.4207.4208/kabi_checked

Boot test: passed

boot-test.log

Kselftests: passed relative

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

bpf, breakpoints, capabilities, clone3, core, cpu-hotplug, cpufreq, drivers/dma-buf, drivers/net/bonding, drivers/net/team, efivarfs, filesystems, filesystems/binderfs, filesystems/epoll, firmware, fpu, ftrace, futex, gpio, intel_pstate, ipc, ir, kcmp, kvm, landlock, lib, livepatch, membarrier, memfd, memory-hotplug, mincore, mount, mqueue, nci, net, net/forwarding, net/mptcp, netfilter, nsfs, openat2, pid_namespace, pidfd, pstore, ptrace, rlimits, rseq, rtc, seccomp, sgx, sigaltstack, size, splice, static_keys, sync, syscall_user_dispatch, sysctl, tc-testing, tdx, timens, timers, tmpfs, tpm2, user, vDSO, vm, x86, zram

Reference

Three test runs were conducted on the reference kernel.
kselftests–mix–ciqlts9_2–run1.log
kselftests–mix–ciqlts9_2–run2.log
kselftests–mix–ciqlts9_2–run3.log

Patch

Two test runs were conducted on the patched kernel.
kselftests–mix–ciqlts9_2-CVE-2023-4206.4207.4208–run1.log
kselftests–mix–ciqlts9_2-CVE-2023-4206.4207.4208–run2.log

Comparison

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

Column    File
--------  ------------------------------------------------------------
Status0   kselftests--mix--ciqlts9_2--run1.log
Status1   kselftests--mix--ciqlts9_2--run2.log
Status2   kselftests--mix--ciqlts9_2--run3.log
Status3   kselftests--mix--ciqlts9_2-CVE-2023-4206.4207.4208--run1.log
Status4   kselftests--mix--ciqlts9_2-CVE-2023-4206.4207.4208--run2.log

TestCase            Status0  Status1  Status2  Status3  Status4  Summary
net:gro.sh          pass     pass     pass     pass     fail     diff
net:txtimestamp.sh  pass     pass     fail     fail     pass     diff
rtc:rtctest         fail     fail     fail     pass     fail     diff
timers:raw_skew     pass     pass     skip     pass     pass     diff

Of the differing results the tests net:gro.sh, net:txtimestamp.sh, rtc:rtctest were known to give inconsistent results before.

The timers:raw_skew test was skipped in the reference test suite due to some external interference

# selftests: timers: raw_skew
# Estimating clock drift: -9.62(est) -10.82(act)	[SKIP]
# 1..0 # SKIP The clock was adjusted externally. Shutdown NTPd or other time sync daemons
ok 7 selftests: timers: raw_skew # SKIP

Kselftests (networking): passed relative

Methodology

In general kselftests all the net/forwarding tests fail (really should be skipped) because of the missing tool dependencies

# selftests: net/forwarding: bridge_igmp.sh
# SKIP: jq not installed
not ok 1 selftests: net/forwarding: bridge_igmp.sh # exit=1

Because the patch deals with networking specifically, an additional batch of tests was carried out after solving the test requirements issues.

sudo make ARCH=$(uname -m) -C tools/testing/selftests TARGETS="net/forwarding" run_tests

The tools/testing/selftests/net/forwarding/forwarding.config file used was created directly from the tools/testing/selftests/net/forwarding/forwarding.config.sample.

Reference

Three test runs were conducted on the reference kernel.
kselftests-net-forwarding–src–ciqlts9_2–run1.log
kselftests-net-forwarding–src–ciqlts9_2–run2.log
kselftests-net-forwarding–src–ciqlts9_2–run3.log

Patch

A single test run was conducted on the patched kernel.
kselftests-net-forwarding–src–ciqlts9_2-CVE-2023-4206.4207.4208–run1.log

Comparison and discussion

Results for the reference and patched kernel are the same.

ktests.xsh table kselftests-net-forwarding*.log

Column    File
--------  ---------------------------------------------------------------------------
Status0   kselftests-net-forwarding--src--ciqlts9_2--run1.log
Status1   kselftests-net-forwarding--src--ciqlts9_2--run2.log
Status2   kselftests-net-forwarding--src--ciqlts9_2--run3.log
Status3   kselftests-net-forwarding--src--ciqlts9_2-CVE-2023-4206.4207.4208--run1.log

TestCase                                        Status0  Status1  Status2  Status3  Summary
net/forwarding:bridge_igmp.sh                   fail     fail     fail     fail     same
net/forwarding:bridge_locked_port.sh            pass     pass     pass     pass     same
net/forwarding:bridge_mld.sh                    fail     fail     fail     fail     same
net/forwarding:bridge_port_isolation.sh         pass     pass     pass     pass     same
net/forwarding:bridge_sticky_fdb.sh             pass     pass     pass     pass     same
net/forwarding:bridge_vlan_aware.sh             fail     fail     fail     fail     same
net/forwarding:bridge_vlan_mcast.sh             fail     fail     fail     fail     same
net/forwarding:bridge_vlan_unaware.sh           pass     pass     pass     pass     same
net/forwarding:custom_multipath_hash.sh         fail     fail     fail     fail     same
net/forwarding:dual_vxlan_bridge.sh             pass     pass     pass     pass     same
net/forwarding:ethtool.sh                       fail     fail     fail     fail     same
net/forwarding:ethtool_extended_state.sh        fail     fail     fail     fail     same
net/forwarding:gre_custom_multipath_hash.sh     fail     fail     fail     fail     same
net/forwarding:gre_inner_v4_multipath.sh        fail     fail     fail     fail     same
net/forwarding:gre_inner_v6_multipath.sh        fail     fail     fail     fail     same
net/forwarding:gre_multipath.sh                 fail     fail     fail     fail     same
net/forwarding:gre_multipath_nh.sh              fail     fail     fail     fail     same
net/forwarding:gre_multipath_nh_res.sh          fail     fail     fail     fail     same
net/forwarding:hw_stats_l3.sh                   fail     fail     fail     fail     same
net/forwarding:hw_stats_l3_gre.sh               fail     fail     fail     fail     same
net/forwarding:ip6_forward_instats_vrf.sh       fail     fail     fail     fail     same
net/forwarding:ip6gre_custom_multipath_hash.sh  fail     fail     fail     fail     same
net/forwarding:ip6gre_flat.sh                   pass     pass     pass     pass     same
net/forwarding:ip6gre_flat_key.sh               pass     pass     pass     pass     same
net/forwarding:ip6gre_flat_keys.sh              pass     pass     pass     pass     same
net/forwarding:ip6gre_hier.sh                   pass     pass     pass     pass     same
net/forwarding:ip6gre_hier_key.sh               pass     pass     pass     pass     same
net/forwarding:ip6gre_hier_keys.sh              pass     pass     pass     pass     same
net/forwarding:ip6gre_inner_v4_multipath.sh     fail     fail     fail     fail     same
net/forwarding:ip6gre_inner_v6_multipath.sh     fail     fail     fail     fail     same
net/forwarding:ipip_flat_gre.sh                 pass     pass     pass     pass     same
net/forwarding:ipip_flat_gre_key.sh             pass     pass     pass     pass     same
net/forwarding:ipip_flat_gre_keys.sh            pass     pass     pass     pass     same
net/forwarding:ipip_hier_gre.sh                 pass     pass     pass     pass     same
net/forwarding:ipip_hier_gre_key.sh             pass     pass     pass     pass     same
net/forwarding:ipip_hier_gre_keys.sh            pass     pass     pass     pass     same
net/forwarding:loopback.sh                      skip     skip     skip     skip     same
net/forwarding:mirror_gre.sh                    fail     fail     fail     fail     same
net/forwarding:mirror_gre_bound.sh              pass     pass     pass     pass     same
net/forwarding:mirror_gre_bridge_1d.sh          pass     pass     pass     pass     same
net/forwarding:mirror_gre_bridge_1d_vlan.sh     fail     fail     fail     fail     same
net/forwarding:mirror_gre_bridge_1q.sh          pass     pass     pass     pass     same
net/forwarding:mirror_gre_bridge_1q_lag.sh      pass     pass     pass     pass     same
net/forwarding:mirror_gre_changes.sh            fail     fail     fail     fail     same
net/forwarding:mirror_gre_flower.sh             fail     fail     fail     fail     same
net/forwarding:mirror_gre_lag_lacp.sh           pass     pass     pass     pass     same
net/forwarding:mirror_gre_neigh.sh              pass     pass     pass     pass     same
net/forwarding:mirror_gre_nh.sh                 pass     pass     pass     pass     same
net/forwarding:mirror_gre_vlan.sh               pass     pass     pass     pass     same
net/forwarding:mirror_gre_vlan_bridge_1q.sh     fail     fail     fail     fail     same
net/forwarding:mirror_vlan.sh                   pass     pass     pass     pass     same
net/forwarding:pedit_dsfield.sh                 pass     pass     pass     pass     same
net/forwarding:pedit_ip.sh                      pass     pass     pass     pass     same
net/forwarding:pedit_l4port.sh                  pass     pass     pass     pass     same
net/forwarding:q_in_vni.sh                      pass     pass     pass     pass     same
net/forwarding:q_in_vni_ipv6.sh                 pass     pass     pass     pass     same
net/forwarding:router.sh                        skip     skip     skip     skip     same
net/forwarding:router_bridge.sh                 pass     pass     pass     pass     same
net/forwarding:router_bridge_vlan.sh            pass     pass     pass     pass     same
net/forwarding:router_broadcast.sh              pass     pass     pass     pass     same
net/forwarding:router_mpath_nh.sh               fail     fail     fail     fail     same
net/forwarding:router_mpath_nh_res.sh           fail     fail     fail     fail     same
net/forwarding:router_multicast.sh              skip     skip     skip     skip     same
net/forwarding:router_multipath.sh              fail     fail     fail     fail     same
net/forwarding:router_nh.sh                     pass     pass     pass     pass     same
net/forwarding:router_vid_1.sh                  pass     pass     pass     pass     same

The list of net/forwarding tests performed is not exhaustive (66 / 92). The net/forwarding:sch_ets.sh test executed right after net/forwarding:router_vid_1.sh causes the machine to hang for more than 10 minutes and the used testing framework interrupts the test suite.

...
ok 66 selftests: net/forwarding: router_vid_1.sh
# selftests: net/forwarding: sch_ets.sh
# TEST: ping vlan 10                                                  [ OK ]
# TEST: ping vlan 11                                                  [ OK ]
# TEST: ping vlan 12                                                  [ OK ]
# Running in priomap mode
# Testing ets bands 3 strict 3, streams 0 1
# TEST: band 0                                                        [ OK ]
# INFO: Expected ratio >95% Measured ratio 100.00
# TEST: band 1                                                        [ OK ]
# INFO: Expected ratio <5% Measured ratio 0
# Testing ets bands 3 strict 3, streams 1 2
ERROR:root:Subprocess exceeded the maximum freeze time 600 s. Terminating
INFO:root:Finished tests. Cleaning up the machine
...

The fix for the problem was deferred to another CVE for the sake of patching efficiency.

pvts-mat added 2 commits March 7, 2025 19:48
…fter-free

jira VULN-6656
cve CVE-2023-4207
commit-author valis <[email protected]>
commit 76e42ae

When fw_change() is called on an existing filter, the whole
tcf_result struct is always copied into the new instance of the filter.

This causes a problem when updating a filter bound to a class,
as tcf_unbind_filter() is always called on the old instance in the
success path, decreasing filter_cnt of the still referenced class
and allowing it to be deleted, leading to a use-after-free.

Fix this by no longer copying the tcf_result struct from the old filter.

Fixes: e35a8ee ("net: sched: fw use RCU")
	Reported-by: valis <[email protected]>
	Reported-by: Bing-Jhong Billy Jheng <[email protected]>
	Signed-off-by: valis <[email protected]>
	Signed-off-by: Jamal Hadi Salim <[email protected]>
	Reviewed-by: Victor Nogueira <[email protected]>
	Reviewed-by: Pedro Tammela <[email protected]>
	Reviewed-by: M A Ramdhan <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
	Signed-off-by: Jakub Kicinski <[email protected]>
(cherry picked from commit 76e42ae)
	Signed-off-by: Marcin Wcisło <[email protected]>
…after-free

jira VULN-6663
cve CVE-2023-4208
commit-author valis <[email protected]>
commit 3044b16

When u32_change() is called on an existing filter, the whole
tcf_result struct is always copied into the new instance of the filter.

This causes a problem when updating a filter bound to a class,
as tcf_unbind_filter() is always called on the old instance in the
success path, decreasing filter_cnt of the still referenced class
and allowing it to be deleted, leading to a use-after-free.

Fix this by no longer copying the tcf_result struct from the old filter.

Fixes: de5df63 ("net: sched: cls_u32 changes to knode must appear atomic to readers")
	Reported-by: valis <[email protected]>
	Reported-by: M A Ramdhan <[email protected]>
	Signed-off-by: valis <[email protected]>
	Signed-off-by: Jamal Hadi Salim <[email protected]>
	Reviewed-by: Victor Nogueira <[email protected]>
	Reviewed-by: Pedro Tammela <[email protected]>
	Reviewed-by: M A Ramdhan <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
	Signed-off-by: Jakub Kicinski <[email protected]>
(cherry picked from commit 3044b16)
	Signed-off-by: Marcin Wcisło <[email protected]>
@pvts-mat pvts-mat marked this pull request as ready for review March 12, 2025 22:12
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.

I agree with the logic that CVE-2023-4206 isn't applicable due to the config. But I would have been ok with applying the change anyway since its so simple.

🥌

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.

I agree with the logic that GHSA-r8pm-459q-x6hw isn't applicable due to the config. But I would have been ok with applying the change anyway since its so simple.

I agree I assume that its because it was so simple because RHEL did fix it in:
https://access.redhat.com/errata/RHSA-2023:7370
kernel: net/sched: multiple vulnerabilities (CVE-2023-3609, CVE-2023-4128, CVE-2023-4206, CVE-2023-4207, CVE-2023-4208)
kernel-5.14.0-284.40.1.el9_2.src.rpm

They also showed that they fixed it in 9.3 as well.
But still in 9.4 that option is not set.

I may still get the fix applied but I'll task it to some people that are working on the edges of the kernel since its in "dead code."

@bmastbergen and @pvts-mat I appreciate you both digging in to validate CVE-2023-4206

:shipit:

@PlaidCat PlaidCat merged commit c18de2f into ctrliq:ciqlts9_2 Mar 13, 2025
2 checks passed
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