Re: [PATCH bpf] bpf, sockmap: reject max_entries > INT_MAX in sock_map_alloc
From: John Fastabend
Date: Tue Sep 22 2026 - 13:07:38 EST
On Tue, Sep 15, 2026 at 08:13:48AM +0000, bot+bpf-ci@xxxxxxxxxx wrote:
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:
[...]
Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
Is 604326b41a6f the commit that introduced this bug?
Looking at that commit, the version of sock_map_alloc() it created did
cap max_entries:
/* Make sure page count doesn't overflow. */
cost = (u64) stab->map.max_entries * sizeof(struct sock *);
if (cost >= U32_MAX - PAGE_SIZE) {
err = -EINVAL;
goto free_stab;
}
This bound limits max_entries to below (U32_MAX - PAGE_SIZE) / 8, about
536,870,400 entries, which is far under INT_MAX. With that bound the
signed iterator in sock_map_free() could not overflow.
The check later moved into bpf_map_charge_init() with the same limit.
The upper bound was actually removed by 0d2c4f964050 ("bpf: Eliminate
rlimit-based memory accounting for sockmap and sockhash maps", v5.11),
which deleted the bpf_map_charge_init() call without replacing the size
check.
Should the Fixes tag be:
Fixes: 0d2c4f964050 ("bpf: Eliminate rlimit-based memory accounting for sockmap and sockhash maps")
The fix is good, its probably worth getting the Fixes tag correct?
diff --git a/net/core/sock_map.c b/net/core/sock_map.c
index ca49bc7f8687c..38df842843289 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)) ||
Otherwise,
Reviewed-by: John Fastabend <john.fastabend@xxxxxxxxx>