CVE-2022-49215

Severity CVSS v4.0:
Pending analysis
Type:
CWE-362 Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
Publication date:
26/02/2025
Last modified:
01/10/2025

Description

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-&gt;state to XSK_UNBOUND, sets xs-&gt;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-&gt;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-&gt;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-&gt;dev in the code. In this<br /> interim, a second process executing xsk_unbind_dev() might have set xs-&gt;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-&gt;dev was the gatekeeper to admit processes into the data plane functions,<br /> but it was replaced with the state variable xs-&gt;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-&gt;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-&gt;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.

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.4 (including) 5.15.33 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.16 (including) 5.16.19 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.17 (including) 5.17.2 (excluding)