CVE-2022-49215
Publication date:
26/02/2025
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
xsk: Fix race at socket teardown<br />
<br />
Fix a race in the xsk socket teardown code that can lead to a NULL pointer<br />
dereference splat. The current xsk unbind code in xsk_unbind_dev() starts by<br />
setting xs->state to XSK_UNBOUND, sets xs->dev to NULL and then waits for any<br />
NAPI processing to terminate using synchronize_net(). After that, the release<br />
code starts to tear down the socket state and free allocated memory.<br />
<br />
BUG: kernel NULL pointer dereference, address: 00000000000000c0<br />
PGD 8000000932469067 P4D 8000000932469067 PUD 0<br />
Oops: 0000 [#1] PREEMPT SMP PTI<br />
CPU: 25 PID: 69132 Comm: grpcpp_sync_ser Tainted: G I 5.16.0+ #2<br />
Hardware name: Dell Inc. PowerEdge R730/0599V5, BIOS 1.2.10 03/09/2015<br />
RIP: 0010:__xsk_sendmsg+0x2c/0x690<br />
[...]<br />
RSP: 0018:ffffa2348bd13d50 EFLAGS: 00010246<br />
RAX: 0000000000000000 RBX: 0000000000000040 RCX: ffff8d5fc632d258<br />
RDX: 0000000000400000 RSI: ffffa2348bd13e10 RDI: ffff8d5fc5489800<br />
RBP: ffffa2348bd13db0 R08: 0000000000000000 R09: 00007ffffffff000<br />
R10: 0000000000000000 R11: 0000000000000000 R12: ffff8d5fc5489800<br />
R13: ffff8d5fcb0f5140 R14: ffff8d5fcb0f5140 R15: 0000000000000000<br />
FS: 00007f991cff9400(0000) GS:ffff8d6f1f700000(0000) knlGS:0000000000000000<br />
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br />
CR2: 00000000000000c0 CR3: 0000000114888005 CR4: 00000000001706e0<br />
Call Trace:<br />
<br />
? aa_sk_perm+0x43/0x1b0<br />
xsk_sendmsg+0xf0/0x110<br />
sock_sendmsg+0x65/0x70<br />
__sys_sendto+0x113/0x190<br />
? debug_smp_processor_id+0x17/0x20<br />
? fpregs_assert_state_consistent+0x23/0x50<br />
? exit_to_user_mode_prepare+0xa5/0x1d0<br />
__x64_sys_sendto+0x29/0x30<br />
do_syscall_64+0x3b/0xc0<br />
entry_SYSCALL_64_after_hwframe+0x44/0xae<br />
<br />
There are two problems with the current code. First, setting xs->dev to NULL<br />
before waiting for all users to stop using the socket is not correct. The<br />
entry to the data plane functions xsk_poll(), xsk_sendmsg(), and xsk_recvmsg()<br />
are all guarded by a test that xs->state is in the state XSK_BOUND and if not,<br />
it returns right away. But one process might have passed this test but still<br />
have not gotten to the point in which it uses xs->dev in the code. In this<br />
interim, a second process executing xsk_unbind_dev() might have set xs->dev to<br />
NULL which will lead to a crash for the first process. The solution here is<br />
just to get rid of this NULL assignment since it is not used anymore. Before<br />
commit 42fddcc7c64b ("xsk: use state member for socket synchronization"),<br />
xs->dev was the gatekeeper to admit processes into the data plane functions,<br />
but it was replaced with the state variable xs->state in the aforementioned<br />
commit.<br />
<br />
The second problem is that synchronize_net() does not wait for any process in<br />
xsk_poll(), xsk_sendmsg(), or xsk_recvmsg() to complete, which means that the<br />
state they rely on might be cleaned up prematurely. This can happen when the<br />
notifier gets called (at driver unload for example) as it uses xsk_unbind_dev().<br />
Solve this by extending the RCU critical region from just the ndo_xsk_wakeup<br />
to the whole functions mentioned above, so that both the test of xs->state ==<br />
XSK_BOUND and the last use of any member of xs is covered by the RCU critical<br />
section. This will guarantee that when synchronize_net() completes, there will<br />
be no processes left executing xsk_poll(), xsk_sendmsg(), or xsk_recvmsg() and<br />
state can be cleaned up safely. Note that we need to drop the RCU lock for the<br />
skb xmit path as it uses functions that might sleep. Due to this, we have to<br />
retest the xs->state after we grab the mutex that protects the skb xmit code<br />
from, among a number of things, an xsk_unbind_dev() being executed from the<br />
notifier at the same time.
Severity CVSS v4.0: Pending analysis
Last modification:
01/10/2025