[PATCH bpf] bpf, sockmap: reject max_entries > INT_MAX in sock_map_alloc
From: Zhao Gongyi
Date: Tue Sep 15 2026 - 03:18:37 EST
From: Zhao Gongyi <zhaogongyi@xxxxxxxxxxxxx>
sock_map_alloc() only rejects max_entries == 0 and never caps the upper
bound. sock_map_free() then walks the sks[] array with a signed int
iterator:
int i;
for (i = 0; i < stab->map.max_entries; i++)
struct sock **psk = &stab->sks[i];
When a SOCKMAP is created with max_entries = 0xffffffff (UINT_MAX), the
allocation of 32 GiB can succeed on large-memory hosts. During free the
counter reaches 0x80000000, wraps to INT_MIN, is sign-extended by movslq
and turned into a ~16 GiB negative offset from stab->sks, pointing far
below the allocation. On a KASAN kernel the shadow check for that
address hits an unmapped shadow page and oopses:
BUG: unable to handle page fault for address: fffff521b59c5a00
RIP: 0010:kasan_check_range+0x107/0x190
Call Trace:
sock_map_free+0x93/0x190
map_create+0x68d/0xb30
__sys_bpf+0x21e/0x2e70
Vmcore confirmed stab->map.max_entries == 0xffffffff, stab->sks ==
0xffffc911ace2d000, and the faulting address sks + (s64)INT_MIN * 8
exactly at 0xffffc90dace2d000. The same Oops triggers on the normal
close()/bpf_map_free_deferred() path whenever such a map is destroyed.
sock_hash_alloc() already bounds its allocation (buckets_num >
U32_MAX / sizeof(bucket)). Reject max_entries > INT_MAX at creation
time so the signed iterator in sock_map_free() never sees a value that
would overflow.
Triggered by syzkaller and reproduced on both a 6.6-based KASAN kernel
and the upstream v7.3-rc2 kernel.
Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
Signed-off-by: Zhao Gongyi <zhaogongyi@xxxxxxxxxxxxx>
---
net/core/sock_map.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/core/sock_map.c b/net/core/sock_map.c
index ca49bc7f8..38df84284 100644
--- a/net/core/sock_map.c
+++ b/net/core/sock_map.c
@@ -41,6 +41,7 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr)
struct bpf_stab *stab;
if (attr->max_entries == 0 ||
+ attr->max_entries > INT_MAX ||
attr->key_size != 4 ||
(attr->value_size != sizeof(u32) &&
attr->value_size != sizeof(u64)) ||
--
2.39.5 (Apple Git-154)