Skip to content

[CBR 7.9] CVE-2023-1281 #401

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 3 commits into from
Jul 10, 2025
Merged

Conversation

pvts-mat
Copy link
Contributor

@pvts-mat pvts-mat commented Jul 9, 2025

[CBR 7.9]
CVE-2023-1281
VULN-7633

Problem

https://nvd.nist.gov/vuln/detail/CVE-2023-1281

Use After Free vulnerability in Linux kernel traffic control index filter (tcindex) allows Privilege Escalation. The imperfect hash area can be updated while packets are traversing, which will cause a use-after-free when 'tcf_exts_exec()' is called with the destroyed tcf_ext. A local attacker user can use this vulnerability to elevate its privileges to root. This issue affects Linux Kernel: from 4.14 before git commit ee05917.

Applicability: yes

The CONFIG_NET_CLS_TCINDEX option including the affected file net/sched/cls_tcindex.c in the build is enabled in configs/kernel-3.10.0-x86_64.config

CONFIG_NET_CLS_TCINDEX=m

The tcindex_set_parms function clearly doesn't contain the rcu-related code from the fix ee05917:

if (cp->perfect)
r = cp->perfect + handle;
else
r = tcindex_lookup(cp, handle) ? : &new_filter_result;

if (r == &new_filter_result) {
struct tcindex_filter *nfp;
struct tcindex_filter __rcu **fp;
f->result.res = r->res;
tcf_exts_change(&f->result.exts, &r->exts);
fp = cp->h + (handle % cp->hash);
for (nfp = rtnl_dereference(*fp);
nfp;
fp = &nfp->next, nfp = rtnl_dereference(*fp))
; /* nothing */
rcu_assign_pointer(*fp, f);
}

Solution

The mainline fix ee05917 makes use of rcu_replace_pointer macro from the Read-Copy-Update synchronization system, file include/linux/rcupdate.h, which is missing from CBR 7.9. It was introduced in a63fc6b and backported as part of this patch.

The ee05917 fix was also imperfect and a fix-of-the fix appeared in 42018a3. It was also included as part of this patch.

The solution therefore consists of backported 3 mainline commits:

Hash Description
a63fc6b RCU system prerequisite
ee05917 The fix proper
42018a3 The follow-up of the fix

No differences relative to the mainline changes are present in the backports.

kABI check: passed

python /mnt/code/kernel-dist-git-el-7.9/SOURCES/check-kabi -k /mnt/code/kernel-dist-git-el-7.9/SOURCES/Module.kabi_x86_64 -s /mnt/build_files/kernel-src-tree-ciqcbr7_9-CVE-2023-1281/Module.symvers
echo $? 

0

Boot test: passed

boot-test.log

Kselftests

Reference

kselftests–ciqcbr7_9–run1.log
kselftests–ciqcbr7_9–run2.log
kselftests–ciqcbr7_9–run3.log

Patch

kselftests–ciqcbr7_9-CVE-2023-1281–run1.log
kselftests–ciqcbr7_9-CVE-2023-1281–run2.log
kselftests–ciqcbr7_9-CVE-2023-1281–run3.log

Specific tests: passed

Given lack of nearly any selftests for networking in CBR 7.9 some tests relating specifically to the tcindex module were carried out. They do not precisely capture the bug, therefore there is no "before and after" comparison with a clearly visible improvemnt; rather a sanity check of the module was done on the patched kernel to prove the proper working of its basic functionality.

The test consists of setting up a dsmark qdisc using some tcindex filters, then generating some traffic with iperf3 and thus confirming that the kernel didn't crash and the network remained functional. The setup is taken from https://lartc.org/lartc.html. (An attempt was made to modify the setup in a controlled manner such that the proper working of tcindex filter could be shown but it failed due to nearly no documentation of tcindex available (the tcindex(8) manpage is a joke) and similar lack of examples on the internet of this obscure feature.)

  1. Reference bandwidth between the hypervisor and the virtual host measurement. The IPs are 192.168.122.1 for the hypervisor and 192.168.122.224 for the virtual host.

    1. Virtual machine:

      [root@ciqcbr-7-9 pvts]# iperf3 -s
      
      -----------------------------------------------------------
      Server listening on 5201
      -----------------------------------------------------------
      Accepted connection from 192.168.122.1, port 43228
      [  5] local 192.168.122.224 port 5201 connected to 192.168.122.1 port 43244
      [ ID] Interval           Transfer     Bandwidth
      [  5]   0.00-1.00   sec  4.14 GBytes  35.6 Gbits/sec                  
      [  5]   1.00-2.00   sec  4.39 GBytes  37.7 Gbits/sec                  
      [  5]   2.00-3.00   sec  4.32 GBytes  37.1 Gbits/sec                  
      [  5]   3.00-4.00   sec  4.37 GBytes  37.6 Gbits/sec                  
      [  5]   4.00-5.00   sec  4.38 GBytes  37.6 Gbits/sec                  
      [  5]   5.00-6.00   sec  4.39 GBytes  37.7 Gbits/sec                  
      [  5]   6.00-7.00   sec  4.40 GBytes  37.8 Gbits/sec                  
      [  5]   7.00-8.00   sec  4.41 GBytes  37.9 Gbits/sec                  
      [  5]   8.00-9.00   sec  4.45 GBytes  38.2 Gbits/sec                  
      [  5]   9.00-10.00  sec  4.45 GBytes  38.2 Gbits/sec                  
      [  5]  10.00-10.03  sec   140 MBytes  37.1 Gbits/sec                  
      - - - - - - - - - - - - - - - - - - - - - - - - -
      [ ID] Interval           Transfer     Bandwidth
      [  5]   0.00-10.03  sec  0.00 Bytes  0.00 bits/sec                  sender
      [  5]   0.00-10.03  sec  43.8 GBytes  37.5 Gbits/sec                  receiver
      -----------------------------------------------------------
      Server listening on 5201
      -----------------------------------------------------------
      
    2. Hypervisor

      $ iperf3 -c 192.168.122.224
      
      [  5] local 192.168.122.1 port 43244 connected to 192.168.122.224 port 5201
      [ ID] Interval           Transfer     Bitrate         Retr  Cwnd
      [  5]   0.00-1.00   sec  4.29 GBytes  36.8 Gbits/sec    0   2.71 MBytes       
      [  5]   1.00-2.00   sec  4.39 GBytes  37.7 Gbits/sec    0   2.71 MBytes       
      [  5]   2.00-3.00   sec  4.32 GBytes  37.1 Gbits/sec    0   2.71 MBytes       
      [  5]   3.00-4.00   sec  4.37 GBytes  37.6 Gbits/sec    0   2.71 MBytes       
      [  5]   4.00-5.00   sec  4.38 GBytes  37.6 Gbits/sec    0   2.71 MBytes       
      [  5]   5.00-6.00   sec  4.39 GBytes  37.7 Gbits/sec    0   2.71 MBytes       
      [  5]   6.00-7.00   sec  4.39 GBytes  37.7 Gbits/sec    0   3.09 MBytes       
      [  5]   7.00-8.00   sec  4.41 GBytes  37.9 Gbits/sec    0   3.09 MBytes       
      [  5]   8.00-9.00   sec  4.45 GBytes  38.2 Gbits/sec    0   3.09 MBytes       
      [  5]   9.00-10.00  sec  4.45 GBytes  38.2 Gbits/sec    0   3.09 MBytes       
      - - - - - - - - - - - - - - - - - - - - - - - - -
      [ ID] Interval           Transfer     Bitrate         Retr
      [  5]   0.00-10.00  sec  43.8 GBytes  37.7 Gbits/sec    0             sender
      [  5]   0.00-10.00  sec  43.8 GBytes  37.7 Gbits/sec                  receiver
      
      iperf Done.
      

    The bandwidth is huge, which is to be expected given that there is no actual physical link involved.

  2. tc setup

    [root@ciqcbr-7-9 pvts]# tc qdisc add dev eth0 handle 1:0 root dsmark indices 64 set_tc_index
    [root@ciqcbr-7-9 pvts]# tc filter add dev eth0 parent 1:0 protocol ip prio 1 tcindex mask 0xfc shift 2
    [root@ciqcbr-7-9 pvts]# tc qdisc add dev eth0 parent 1:0 handle 2:0 cbq bandwidth 10Mbit cell 8 avpkt 1000 mpu 64
    [root@ciqcbr-7-9 pvts]# tc class add dev eth0 parent 2:0 classid 2:1 cbq bandwidth 10Mbit rate 1500Kbit avpkt 1000 prio 1 bounded isolated allot 1514 weight 1 maxburst 10
    [root@ciqcbr-7-9 pvts]# tc qdisc add dev eth0 parent 2:1 pfifo limit 5
    [root@ciqcbr-7-9 pvts]# tc filter add dev eth0 parent 2:0 protocol ip prio 1 handle 0x2e tcindex classid 2:1 pass_on
    
  3. Display the classes statistics for control

    [root@ciqcbr-7-9 pvts]# tc -s class show dev eth0 
    class cbq 2: root rate 10Mbit (bounded,isolated) prio no-transmit
     Sent 256 bytes 2 pkt (dropped 0, overlimits 0 requeues 0) 
     backlog 0b 0p requeues 0 
      borrowed 0 overactions 0 avgidle 12500 undertime 0
    class cbq 2:1 parent 2: leaf 8001: rate 1500Kbit (bounded,isolated) prio 1
     Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
     backlog 0b 0p requeues 0 
      borrowed 0 overactions 0 avgidle 846984 undertime 0
    
  4. Run iperf3 again

    $ iperf3 -c  192.168.122.224
    Connecting to host 192.168.122.224, port 5201
    [  5] local 192.168.122.1 port 56614 connected to 192.168.122.224 port 5201
    [ ID] Interval           Transfer     Bitrate         Retr  Cwnd
    [  5]   0.00-1.00   sec  4.41 GBytes  37.9 Gbits/sec    0   1.44 MBytes       
    [  5]   1.00-2.00   sec  4.54 GBytes  39.0 Gbits/sec    0   3.08 MBytes       
    [  5]   2.00-3.00   sec  4.40 GBytes  37.8 Gbits/sec    0   3.08 MBytes       
    [  5]   3.00-4.00   sec  4.33 GBytes  37.2 Gbits/sec    0   3.08 MBytes       
    [  5]   4.00-5.00   sec  4.36 GBytes  37.5 Gbits/sec    0   3.08 MBytes       
    [  5]   5.00-6.00   sec  4.36 GBytes  37.5 Gbits/sec    0   3.08 MBytes       
    [  5]   6.00-7.00   sec  4.36 GBytes  37.5 Gbits/sec    0   3.08 MBytes       
    [  5]   7.00-8.00   sec  4.36 GBytes  37.5 Gbits/sec    0   3.08 MBytes       
    [  5]   8.00-9.00   sec  4.35 GBytes  37.3 Gbits/sec    0   3.08 MBytes       
    [  5]   9.00-10.00  sec  4.36 GBytes  37.5 Gbits/sec    0   3.08 MBytes       
    - - - - - - - - - - - - - - - - - - - - - - - - -
    [ ID] Interval           Transfer     Bitrate         Retr
    [  5]   0.00-10.00  sec  43.8 GBytes  37.7 Gbits/sec    0             sender
    [  5]   0.00-10.00  sec  43.8 GBytes  37.6 Gbits/sec                  receiver
    
    iperf Done.
    

    The network is functional.

  5. Display the classes statistics on the VM again

    [root@ciqcbr-7-9 pvts]# tc -s class show dev eth0 
    class cbq 2: root rate 10Mbit (bounded,isolated) prio no-transmit
     Sent 12317427 bytes 186622 pkt (dropped 0, overlimits 0 requeues 0) 
     backlog 0b 0p requeues 0 
      borrowed 0 overactions 0 avgidle 12500 undertime 0
    class cbq 2:1 parent 2: leaf 8001: rate 1500Kbit (bounded,isolated) prio 1
     Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
     backlog 0b 0p requeues 0 
      borrowed 0 overactions 0 avgidle 846984 undertime 0
    

    All traffic was handled by the cbq class 2:.

pvts-mat added 3 commits July 8, 2025 02:07
jira VULN-7633
cve-pre CVE-2023-1281
commit-author Paul E. McKenney <[email protected]>
commit a63fc6b

Although the rcu_swap_protected() macro follows the example of
swap(), the interactions with RCU make its update of its argument
somewhat counter-intuitive.  This commit therefore introduces
an rcu_replace_pointer() that returns the old value of the RCU
pointer instead of doing the argument update.  Once all the uses of
rcu_swap_protected() are updated to instead use rcu_replace_pointer(),
rcu_swap_protected() will be removed.

Link: https://lore.kernel.org/lkml/CAHk-=wiAsJLw1egFEE=Z7-GGtM6wcvtyytXZA1+BHqta4gg6Hw@mail.gmail.com/
	Reported-by: Linus Torvalds <[email protected]>
[ paulmck: From rcu_replace() to rcu_replace_pointer() per Ingo Molnar. ]
	Signed-off-by: Paul E. McKenney <[email protected]>
	Cc: Bart Van Assche <[email protected]>
	Cc: Christoph Hellwig <[email protected]>
	Cc: Hannes Reinecke <[email protected]>
	Cc: Johannes Thumshirn <[email protected]>
	Cc: Shane M Seymour <[email protected]>
	Cc: Martin K. Petersen <[email protected]>
(cherry picked from commit a63fc6b)
	Signed-off-by: Marcin Wcisło <[email protected]>
jira VULN-7633
cve CVE-2023-1281
commit-author Pedro Tammela <[email protected]>
commit ee05917

The imperfect hash area can be updated while packets are traversing,
which will cause a use-after-free when 'tcf_exts_exec()' is called
with the destroyed tcf_ext.

CPU 0:               CPU 1:
tcindex_set_parms    tcindex_classify
tcindex_lookup
                     tcindex_lookup
tcf_exts_change
                     tcf_exts_exec [UAF]

Stop operating on the shared area directly, by using a local copy,
and update the filter with 'rcu_replace_pointer()'. Delete the old
filter version only after a rcu grace period elapsed.

Fixes: 9b0d444 ("net: sched: avoid atomic swap in tcf_exts_change")
	Reported-by: valis <[email protected]>
	Suggested-by: valis <[email protected]>
	Signed-off-by: Jamal Hadi Salim <[email protected]>
	Signed-off-by: Pedro Tammela <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
	Signed-off-by: Jakub Kicinski <[email protected]>
(cherry picked from commit ee05917)
	Signed-off-by: Marcin Wcisło <[email protected]>
jira VULN-7633
cve CVE-2023-1281
commit-author Pedro Tammela <[email protected]>
commit 42018a3

Syzkaller found an issue where a handle greater than 16 bits would trigger
a null-ptr-deref in the imperfect hash area update.

general protection fault, probably for non-canonical address
0xdffffc0000000015: 0000 [ctrliq#1] PREEMPT SMP KASAN
KASAN: null-ptr-deref in range [0x00000000000000a8-0x00000000000000af]
CPU: 0 PID: 5070 Comm: syz-executor456 Not tainted
6.2.0-rc7-syzkaller-00112-gc68f345b7c42 #0
Hardware name: Google Google Compute Engine/Google Compute Engine,
BIOS Google 01/21/2023
RIP: 0010:tcindex_set_parms+0x1a6a/0x2990 net/sched/cls_tcindex.c:509
Code: 01 e9 e9 fe ff ff 4c 8b bd 28 fe ff ff e8 0e 57 7d f9 48 8d bb
a8 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c
02 00 0f 85 94 0c 00 00 48 8b 85 f8 fd ff ff 48 8b 9b a8 00
RSP: 0018:ffffc90003d3ef88 EFLAGS: 00010202
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000015 RSI: ffffffff8803a102 RDI: 00000000000000a8
RBP: ffffc90003d3f1d8 R08: 0000000000000001 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000000 R12: ffff88801e2b10a8
R13: dffffc0000000000 R14: 0000000000030000 R15: ffff888017b3be00
FS: 00005555569af300(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000056041c6d2000 CR3: 000000002bfca000 CR4: 00000000003506f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
tcindex_change+0x1ea/0x320 net/sched/cls_tcindex.c:572
tc_new_tfilter+0x96e/0x2220 net/sched/cls_api.c:2155
rtnetlink_rcv_msg+0x959/0xca0 net/core/rtnetlink.c:6132
netlink_rcv_skb+0x165/0x440 net/netlink/af_netlink.c:2574
netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline]
netlink_unicast+0x547/0x7f0 net/netlink/af_netlink.c:1365
netlink_sendmsg+0x91b/0xe10 net/netlink/af_netlink.c:1942
sock_sendmsg_nosec net/socket.c:714 [inline]
sock_sendmsg+0xd3/0x120 net/socket.c:734
____sys_sendmsg+0x334/0x8c0 net/socket.c:2476
___sys_sendmsg+0x110/0x1b0 net/socket.c:2530
__sys_sendmmsg+0x18f/0x460 net/socket.c:2616
__do_sys_sendmmsg net/socket.c:2645 [inline]
__se_sys_sendmmsg net/socket.c:2642 [inline]
__x64_sys_sendmmsg+0x9d/0x100 net/socket.c:2642
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80

Fixes: ee05917 ("net/sched: tcindex: update imperfect hash filters respecting rcu")
	Signed-off-by: Jamal Hadi Salim <[email protected]>
	Signed-off-by: Pedro Tammela <[email protected]>
	Reported-by: syzbot <[email protected]>
	Reviewed-by: Eric Dumazet <[email protected]>
	Signed-off-by: David S. Miller <[email protected]>
(cherry picked from commit 42018a3)
	Signed-off-by: Marcin Wcisło <[email protected]>
@pvts-mat
Copy link
Contributor Author

pvts-mat commented Jul 9, 2025

Btw, the tcindex really should be dropped, see #155.
Btw2, others are doing it too https://starlabs.sg/blog/2023/06-breaking-the-code-exploiting-and-examining-cve-2023-1829-in-cls_tcindex-classifier-vulnerability/#vulnerability-analysis.
So do we, even, see 4f4b15b, bd65660, 7290460
CVE-2023-1829 for CBR 7.9 when?

@PlaidCat
Copy link
Collaborator

PlaidCat commented Jul 9, 2025

Btw, the tcindex really should be dropped, see #155. Btw2, others are doing it too https://starlabs.sg/blog/2023/06-breaking-the-code-exploiting-and-examining-cve-2023-1829-in-cls_tcindex-classifier-vulnerability/#vulnerability-analysis. So do we, even, see 4f4b15b, bd65660, 7290460 CVE-2023-1829 for CBR 7.9 when?

I can send it over but RHEL is no planned fix and denylisting the module
https://access.redhat.com/security/cve/CVE-2023-1829

For Red Hat Enterprise Linux 7, please use the mitigation to disable module cls_tcindex, because similar use-after-free issues also exists in the Linux Kernel's traffic control index filter and will not be fixed before Red Hat Enterprise Linux 8.

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

@thefossguy-ciq thefossguy-ciq left a comment

Choose a reason for hiding this comment

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

🚤

@PlaidCat PlaidCat merged commit 3067830 into ctrliq:ciqcbr7_9 Jul 10, 2025
1 check 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