Thread (5 messages) 5 messages, 4 authors, 28d ago

Re: [PATCH bpf] bpf, sockmap: reject max_entries > INT_MAX in sock_map_alloc

flat view

From: John Fastabend <john.fastabend@gmail.com>
Date: 2026-09-22 17:07:01
Also in: bpf, lkml

On Tue, Sep 15, 2026 at 08:13:48AM +0000, bot+bpf-ci@kernel.org wrote:
quoted
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:
[...]
quoted
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?
quoted
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@gmail.com>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help