Re: [PATCH bpf v3 2/2] selftests/bpf: Add regression test for queue/stack map size limit

Andrii Nakryiko <[email protected]>
Newsgroups org.kernel.vger.bpf
Message-ID <CAEf4BzbGe74OuUKiDz7oBrWzQCD54JVhYuCTQEWNHOHmnBEtbQ@mail.gmail.com>
On Mon, Aug 10, 2026 at 7:00 AM <[email protected]> wrote:
>
> From: Yuan Chen <[email protected]>
>
> Verify that queue/stack maps whose element storage would overflow the
> u32 head/tail index multiplication are rejected at creation time, and
> that max_entries == U32_MAX (which would wrap the u32 capacity counter
> to 0) is rejected as well.
>
> Signed-off-by: Yuan Chen <[email protected]>
> ---
>  .../bpf/prog_tests/queue_stack_map.c          | 49 +++++++++++++++++++
>  1 file changed, 49 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c b/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c
> index 41441325e179..043cbe92e2ba 100644
> --- a/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c
> +++ b/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c
> @@ -2,6 +2,8 @@
>  #include <test_progs.h>
>  #include <network_helpers.h>
>
> +#define U32_MAX ((u32)UINT_MAX)
> +
>  enum {
>         QUEUE,
>         STACK,
> @@ -101,8 +103,55 @@ static void test_queue_stack_map_by_type(int type)
>         bpf_object__close(obj);
>  }
>
> +static void test_queue_stack_map_alloc_check(void)
> +{
> +       LIBBPF_OPTS(bpf_map_create_opts, opts);
> +       const __u32 big_value = 1 << 20; /* 1MB */
> +       int fd, saved_errno;
> +
> +       /*
> +        * Regression test for the u32 index overflow in queue/stack maps:
> +        * a map whose element storage (max_entries * value_size) exceeds
> +        * U32_MAX bytes must be rejected at creation time, otherwise the
> +        * u32 head/tail index multiplication wraps and push/peek/pop
> +        * address the wrong element. 8192 * 1MB = 8GB > U32_MAX.
> +        */
> +       fd = bpf_map_create(BPF_MAP_TYPE_QUEUE, NULL, 0, big_value, 8192, &opts);
> +       saved_errno = errno;
> +       ASSERT_LT(fd, 0, "queue_oversize_fd");
> +       ASSERT_EQ(saved_errno, E2BIG, "queue_oversize_errno");
> +       if (fd >= 0)
> +               close(fd);
> +
> +       /*
> +        * max_entries == U32_MAX would make the u32 capacity counter
> +        * qs->size (max_entries + 1) wrap to 0, permanently breaking the
> +        * map, so it must be rejected as well.
> +        */
> +       fd = bpf_map_create(BPF_MAP_TYPE_QUEUE, NULL, 0, 1, U32_MAX, &opts);
> +       saved_errno = errno;
> +       ASSERT_LT(fd, 0, "queue_u32max_fd");
> +       ASSERT_EQ(saved_errno, E2BIG, "queue_u32max_errno");

Just ASSERT_EQ(fd, -E2BIG)? libbpf returns an error value directly.

> +       if (fd >= 0)
> +               close(fd);
> +
> +       fd = bpf_map_create(BPF_MAP_TYPE_STACK, NULL, 0, big_value, 8192, &opts);
> +       saved_errno = errno;
> +       ASSERT_LT(fd, 0, "stack_oversize_fd");
> +       ASSERT_EQ(saved_errno, E2BIG, "stack_oversize_errno");
> +       if (fd >= 0)
> +               close(fd);
> +
> +       /* A normal-sized map must still be created successfully. */
> +       fd = bpf_map_create(BPF_MAP_TYPE_QUEUE, NULL, 0, 64, 100, &opts);
> +       ASSERT_GE(fd, 0, "queue_normal_fd");
> +       if (fd >= 0)
> +               close(fd);
> +}
> +
>  void test_queue_stack_map(void)
>  {
>         test_queue_stack_map_by_type(QUEUE);
>         test_queue_stack_map_by_type(STACK);
> +       test_queue_stack_map_alloc_check();
>  }
> --
> 2.54.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.