From: Yuan Chen queue/stack maps address elements[] with a u32 head/tail index multiplied by value_size, so maps whose element storage exceeds U32_MAX bytes must be rejected at creation time (see the fix in queue_stack_map_alloc_check()). Verify that creating a queue/stack map with max_entries * value_size > U32_MAX (8192 * 1MB) fails with -E2BIG, and that a normal-sized map is still created successfully. Signed-off-by: Yuan Chen --- .../bpf/prog_tests/queue_stack_map.c | 34 +++++++++++++++++++ 1 file changed, 34 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..6f8ac285e719 100644 --- a/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c +++ b/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c @@ -101,8 +101,42 @@ 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); + + 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