CVE-2024-56664
Publication date:
27/12/2024
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
bpf, sockmap: Fix race between element replace and close()<br />
<br />
Element replace (with a socket different from the one stored) may race<br />
with socket&#39;s close() link popping & unlinking. __sock_map_delete()<br />
unconditionally unrefs the (wrong) element:<br />
<br />
// set map[0] = s0<br />
map_update_elem(map, 0, s0)<br />
<br />
// drop fd of s0<br />
close(s0)<br />
sock_map_close()<br />
lock_sock(sk) (s0!)<br />
sock_map_remove_links(sk)<br />
link = sk_psock_link_pop()<br />
sock_map_unlink(sk, link)<br />
sock_map_delete_from_link<br />
// replace map[0] with s1<br />
map_update_elem(map, 0, s1)<br />
sock_map_update_elem<br />
(s1!) lock_sock(sk)<br />
sock_map_update_common<br />
psock = sk_psock(sk)<br />
spin_lock(&stab->lock)<br />
osk = stab->sks[idx]<br />
sock_map_add_link(..., &stab->sks[idx])<br />
sock_map_unref(osk, &stab->sks[idx])<br />
psock = sk_psock(osk)<br />
sk_psock_put(sk, psock)<br />
if (refcount_dec_and_test(&psock))<br />
sk_psock_drop(sk, psock)<br />
spin_unlock(&stab->lock)<br />
unlock_sock(sk)<br />
__sock_map_delete<br />
spin_lock(&stab->lock)<br />
sk = *psk // s1 replaced s0; sk == s1<br />
if (!sk_test || sk_test == sk) // sk_test (s0) != sk (s1); no branch<br />
sk = xchg(psk, NULL)<br />
if (sk)<br />
sock_map_unref(sk, psk) // unref s1; sks[idx] will dangle<br />
psock = sk_psock(sk)<br />
sk_psock_put(sk, psock)<br />
if (refcount_dec_and_test())<br />
sk_psock_drop(sk, psock)<br />
spin_unlock(&stab->lock)<br />
release_sock(sk)<br />
<br />
Then close(map) enqueues bpf_map_free_deferred, which finally calls<br />
sock_map_free(). This results in some refcount_t warnings along with<br />
a KASAN splat [1].<br />
<br />
Fix __sock_map_delete(), do not allow sock_map_unref() on elements that<br />
may have been replaced.<br />
<br />
[1]:<br />
BUG: KASAN: slab-use-after-free in sock_map_free+0x10e/0x330<br />
Write of size 4 at addr ffff88811f5b9100 by task kworker/u64:12/1063<br />
<br />
CPU: 14 UID: 0 PID: 1063 Comm: kworker/u64:12 Not tainted 6.12.0+ #125<br />
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux 1.16.3-1-1 04/01/2014<br />
Workqueue: events_unbound bpf_map_free_deferred<br />
Call Trace:<br />
<br />
dump_stack_lvl+0x68/0x90<br />
print_report+0x174/0x4f6<br />
kasan_report+0xb9/0x190<br />
kasan_check_range+0x10f/0x1e0<br />
sock_map_free+0x10e/0x330<br />
bpf_map_free_deferred+0x173/0x320<br />
process_one_work+0x846/0x1420<br />
worker_thread+0x5b3/0xf80<br />
kthread+0x29e/0x360<br />
ret_from_fork+0x2d/0x70<br />
ret_from_fork_asm+0x1a/0x30<br />
<br />
<br />
Allocated by task 1202:<br />
kasan_save_stack+0x1e/0x40<br />
kasan_save_track+0x10/0x30<br />
__kasan_slab_alloc+0x85/0x90<br />
kmem_cache_alloc_noprof+0x131/0x450<br />
sk_prot_alloc+0x5b/0x220<br />
sk_alloc+0x2c/0x870<br />
unix_create1+0x88/0x8a0<br />
unix_create+0xc5/0x180<br />
__sock_create+0x241/0x650<br />
__sys_socketpair+0x1ce/0x420<br />
__x64_sys_socketpair+0x92/0x100<br />
do_syscall_64+0x93/0x180<br />
entry_SYSCALL_64_after_hwframe+0x76/0x7e<br />
<br />
Freed by task 46:<br />
kasan_save_stack+0x1e/0x40<br />
kasan_save_track+0x10/0x30<br />
kasan_save_free_info+0x37/0x60<br />
__kasan_slab_free+0x4b/0x70<br />
kmem_cache_free+0x1a1/0x590<br />
__sk_destruct+0x388/0x5a0<br />
sk_psock_destroy+0x73e/0xa50<br />
process_one_work+0x846/0x1420<br />
worker_thread+0x5b3/0xf80<br />
kthread+0x29e/0x360<br />
ret_from_fork+0x2d/0x70<br />
ret_from_fork_asm+0x1a/0x30<br />
<br />
The bu<br />
---truncated---
Severity CVSS v4.0: Pending analysis
Last modification:
10/04/2025