CVE-2024-43887
Publication date:
26/08/2024
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
net/tcp: Disable TCP-AO static key after RCU grace period<br />
<br />
The lifetime of TCP-AO static_key is the same as the last<br />
tcp_ao_info. On the socket destruction tcp_ao_info ceases to be<br />
with RCU grace period, while tcp-ao static branch is currently deferred<br />
destructed. The static key definition is<br />
: DEFINE_STATIC_KEY_DEFERRED_FALSE(tcp_ao_needed, HZ);<br />
<br />
which means that if RCU grace period is delayed by more than a second<br />
and tcp_ao_needed is in the process of disablement, other CPUs may<br />
yet see tcp_ao_info which atent dead, but soon-to-be.<br />
And that breaks the assumption of static_key_fast_inc_not_disabled().<br />
<br />
See the comment near the definition:<br />
> * The caller must make sure that the static key can&#39;t get disabled while<br />
> * in this function. It doesn&#39;t patch jump labels, only adds a user to<br />
> * an already enabled static key.<br />
<br />
Originally it was introduced in commit eb8c507296f6 ("jump_label:<br />
Prevent key->enabled int overflow"), which is needed for the atomic<br />
contexts, one of which would be the creation of a full socket from a<br />
request socket. In that atomic context, it&#39;s known by the presence<br />
of the key (md5/ao) that the static branch is already enabled.<br />
So, the ref counter for that static branch is just incremented<br />
instead of holding the proper mutex.<br />
static_key_fast_inc_not_disabled() is just a helper for such usage<br />
case. But it must not be used if the static branch could get disabled<br />
in parallel as it&#39;s not protected by jump_label_mutex and as a result,<br />
races with jump_label_update() implementation details.<br />
<br />
Happened on netdev test-bot[1], so not a theoretical issue:<br />
<br />
[] jump_label: Fatal kernel bug, unexpected op at tcp_inbound_hash+0x1a7/0x870 [ffffffffa8c4e9b7] (eb 50 0f 1f 44 != 66 90 0f 1f 00)) size:2 type:1<br />
[] ------------[ cut here ]------------<br />
[] kernel BUG at arch/x86/kernel/jump_label.c:73!<br />
[] Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI<br />
[] CPU: 3 PID: 243 Comm: kworker/3:3 Not tainted 6.10.0-virtme #1<br />
[] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014<br />
[] Workqueue: events jump_label_update_timeout<br />
[] RIP: 0010:__jump_label_patch+0x2f6/0x350<br />
...<br />
[] Call Trace:<br />
[] <br />
[] arch_jump_label_transform_queue+0x6c/0x110<br />
[] __jump_label_update+0xef/0x350<br />
[] __static_key_slow_dec_cpuslocked.part.0+0x3c/0x60<br />
[] jump_label_update_timeout+0x2c/0x40<br />
[] process_one_work+0xe3b/0x1670<br />
[] worker_thread+0x587/0xce0<br />
[] kthread+0x28a/0x350<br />
[] ret_from_fork+0x31/0x70<br />
[] ret_from_fork_asm+0x1a/0x30<br />
[] <br />
[] Modules linked in: veth<br />
[] ---[ end trace 0000000000000000 ]---<br />
[] RIP: 0010:__jump_label_patch+0x2f6/0x350<br />
<br />
[1]: https://netdev-3.bots.linux.dev/vmksft-tcp-ao-dbg/results/696681/5-connect-deny-ipv6/stderr
Severity CVSS v4.0: Pending analysis
Last modification:
05/09/2024