CVE-2023-54090
Fecha de publicación:
24/12/2025
*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
ixgbe: Fix panic during XDP_TX with > 64 CPUs<br />
<br />
Commit 4fe815850bdc ("ixgbe: let the xdpdrv work with more than 64 cpus")<br />
adds support to allow XDP programs to run on systems with more than<br />
64 CPUs by locking the XDP TX rings and indexing them using cpu % 64<br />
(IXGBE_MAX_XDP_QS).<br />
<br />
Upon trying this out patch on a system with more than 64 cores,<br />
the kernel paniced with an array-index-out-of-bounds at the return in<br />
ixgbe_determine_xdp_ring in ixgbe.h, which means ixgbe_determine_xdp_q_idx<br />
was just returning the cpu instead of cpu % IXGBE_MAX_XDP_QS. An example<br />
splat:<br />
<br />
==========================================================================<br />
UBSAN: array-index-out-of-bounds in<br />
/var/lib/dkms/ixgbe/5.18.6+focal-1/build/src/ixgbe.h:1147:26<br />
index 65 is out of range for type &#39;ixgbe_ring *[64]&#39;<br />
==========================================================================<br />
BUG: kernel NULL pointer dereference, address: 0000000000000058<br />
#PF: supervisor read access in kernel mode<br />
#PF: error_code(0x0000) - not-present page<br />
PGD 0 P4D 0<br />
Oops: 0000 [#1] SMP NOPTI<br />
CPU: 65 PID: 408 Comm: ksoftirqd/65<br />
Tainted: G IOE 5.15.0-48-generic #54~20.04.1-Ubuntu<br />
Hardware name: Dell Inc. PowerEdge R640/0W23H8, BIOS 2.5.4 01/13/2020<br />
RIP: 0010:ixgbe_xmit_xdp_ring+0x1b/0x1c0 [ixgbe]<br />
Code: 3b 52 d4 cf e9 42 f2 ff ff 66 0f 1f 44 00 00 0f 1f 44 00 00 55 b9<br />
00 00 00 00 48 89 e5 41 57 41 56 41 55 41 54 53 48 83 ec 08 0f b7<br />
47 58 0f b7 47 5a 0f b7 57 54 44 0f b7 76 08 66 41 39 c0<br />
RSP: 0018:ffffbc3fcd88fcb0 EFLAGS: 00010282<br />
RAX: ffff92a253260980 RBX: ffffbc3fe68b00a0 RCX: 0000000000000000<br />
RDX: ffff928b5f659000 RSI: ffff928b5f659000 RDI: 0000000000000000<br />
RBP: ffffbc3fcd88fce0 R08: ffff92b9dfc20580 R09: 0000000000000001<br />
R10: 3d3d3d3d3d3d3d3d R11: 3d3d3d3d3d3d3d3d R12: 0000000000000000<br />
R13: ffff928b2f0fa8c0 R14: ffff928b9be20050 R15: 000000000000003c<br />
FS: 0000000000000000(0000) GS:ffff92b9dfc00000(0000)<br />
knlGS:0000000000000000<br />
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br />
CR2: 0000000000000058 CR3: 000000011dd6a002 CR4: 00000000007706e0<br />
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000<br />
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400<br />
PKRU: 55555554<br />
Call Trace:<br />
<br />
ixgbe_poll+0x103e/0x1280 [ixgbe]<br />
? sched_clock_cpu+0x12/0xe0<br />
__napi_poll+0x30/0x160<br />
net_rx_action+0x11c/0x270<br />
__do_softirq+0xda/0x2ee<br />
run_ksoftirqd+0x2f/0x50<br />
smpboot_thread_fn+0xb7/0x150<br />
? sort_range+0x30/0x30<br />
kthread+0x127/0x150<br />
? set_kthread_struct+0x50/0x50<br />
ret_from_fork+0x1f/0x30<br />
<br />
<br />
I think this is how it happens:<br />
<br />
Upon loading the first XDP program on a system with more than 64 CPUs,<br />
ixgbe_xdp_locking_key is incremented in ixgbe_xdp_setup. However,<br />
immediately after this, the rings are reconfigured by ixgbe_setup_tc.<br />
ixgbe_setup_tc calls ixgbe_clear_interrupt_scheme which calls<br />
ixgbe_free_q_vectors which calls ixgbe_free_q_vector in a loop.<br />
ixgbe_free_q_vector decrements ixgbe_xdp_locking_key once per call if<br />
it is non-zero. Commenting out the decrement in ixgbe_free_q_vector<br />
stopped my system from panicing.<br />
<br />
I suspect to make the original patch work, I would need to load an XDP<br />
program and then replace it in order to get ixgbe_xdp_locking_key back<br />
above 0 since ixgbe_setup_tc is only called when transitioning between<br />
XDP and non-XDP ring configurations, while ixgbe_xdp_locking_key is<br />
incremented every time ixgbe_xdp_setup is called.<br />
<br />
Also, ixgbe_setup_tc can be called via ethtool --set-channels, so this<br />
becomes another path to decrement ixgbe_xdp_locking_key to 0 on systems<br />
with more than 64 CPUs.<br />
<br />
Since ixgbe_xdp_locking_key only protects the XDP_TX path and is tied<br />
to the number of CPUs present, there is no reason to disable it upon<br />
unloading an XDP program. To avoid confusion, I have moved enabling<br />
ixgbe_xdp_locking_key into ixgbe_sw_init, which is part of the probe path.
Gravedad: Pendiente de análisis
Última modificación:
24/12/2025