From: Masoud Aghasi <maghasi@disroot.org>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: bpf <bpf@vger.kernel.org>, Andrii Nakryiko <andrii@kernel.org>,
Eduard <eddyz87@gmail.com>, Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Kumar Kartikeya Dwivedi <memxor@gmail.com>,
Martin KaFai Lau <martin.lau@linux.dev>,
Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
Jiri Olsa <jolsa@kernel.org>,
Emil Tsalapatis <emil@etsalapatis.com>,
Ihor Solodrai <ihor.solodrai@linux.dev>,
John Fastabend <john.fastabend@gmail.com>,
Brian Vazquez <brianvv@google.com>
Subject: Re: [PATCH v3] bpf: Fix u32 overflow issue in map batch operations
Date: Sun, 6 Sep 2026 23:42:46 +0100 [thread overview]
Message-ID: <5574f80b-104c-48d7-8d1e-74b1cc720a41@disroot.org> (raw)
In-Reply-To: <CAADnVQLX5bjLTPm8Ch0wNuojHrKw6R5iJDBRsMJwrWMSupVwew@mail.gmail.com>
On 04/09/2026 05:45, Alexei Starovoitov wrote:
> On Thu, Sep 3, 2026 at 1:28 AM Masoud Aghasi <maghasi@disroot.org> wrote:
>>
>> Several map batch operation implementations such as
>> generic_map_lookup_batch() use calculations in the form of
>> "values + cp * map->value_size" to compute the desired userspace memory
>> address for reading or writing. This can overflow the u32 type
>> (the result of "cp * map->value_size") when the map size exceeds 4GB.
>>
>> generic_map_lookup_batch() may corrupt values for some keys in
>> userspace memory, and in some cases it mismatches values for some keys
>> while still reporting success.
>
> without selftest I have to assume that this is AI hallucination.
>
> pw-bot: cr
I post the selftest here to make it easier to reproduce the bug
and also not having issues with the CI. I also added the output that
I received locally, which shows tests fail for map sizes bigger
than 4GB. I hope it helps, please let me know if you need any
more clarifications.
```c
// SPDX-License-Identifier: GPL-2.0
#include <test_progs.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#define TEST_BATCH_LOOKUP 1
#define TEST_BATCH_UPDATE 2
static void validate_batch_lookup(const int map_fd, const __u32 max_entries,
void *keys, void *values)
{
int err;
__u32 out_batch, count;
/* Do batch lookup on the map and validate the result */
count = max_entries;
err = bpf_map_lookup_batch(map_fd, NULL, &out_batch, keys, values,
&count, NULL);
if (!ASSERT_EQ(err, 0, "map_lookup_batch"))
return;
if (!ASSERT_EQ(count, max_entries, "map_lookup_batch_count"))
return;
if (!ASSERT_EQ(*(__u64 *)values, 0llu, "map_lookup_batch_value"))
return;
}
static void validate_batch_update(const int map_fd, const __u32 max_entries,
const __u32 value_size, void *keys,
void *values)
{
int err;
__u32 count, key;
/* Do batch update on the map */
count = max_entries;
err = bpf_map_update_batch(map_fd, keys, values, &count, NULL);
if (!ASSERT_EQ(err, 0, "map_update_batch"))
return;
if (!ASSERT_EQ(count, max_entries, "map_update_batch_count"))
return;
/* Validate the last value */
key = max_entries - 1;
err = bpf_map_lookup_elem(map_fd, &key, values);
if (!ASSERT_EQ(err, 0, "map_update_batch_lookup"))
return;
if (!ASSERT_EQ(*(__u64 *)values, key, "map_update_batch_value"))
return;
}
static void test_array_batch_overflow(const __u32 max_entries,
const __u32 value_size, int test_type)
{
int map_fd, err;
void *keys, *values;
__u32 i;
const __u32 key_size = sizeof(int);
keys = calloc(max_entries, key_size);
if (!keys) {
test__skip();
return;
}
values = calloc(max_entries, value_size);
if (!values) {
free(keys);
test__skip();
return;
}
map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "array_map", key_size,
value_size, max_entries, NULL);
if (map_fd < 0) {
if (errno == ENOMEM)
test__skip();
else
ASSERT_GE(map_fd, 0, "map_create");
free(keys);
free(values);
return;
}
/* Update all elements with unique values */
for (i = 0; i < max_entries; i++) {
*(__u32 *)(keys + (__u64)i * key_size) = i;
*(__u64 *)(values + (__u64)i * value_size) = (__u64)i;
err = bpf_map_update_elem(map_fd, &i,
values + (__u64)i * value_size, 0);
if (err) {
ASSERT_EQ(err, 0, "map_update_elem");
goto cleanup;
}
}
if (test_type == TEST_BATCH_LOOKUP)
validate_batch_lookup(map_fd, max_entries, keys, values);
else if (test_type == TEST_BATCH_UPDATE)
validate_batch_update(map_fd, max_entries, value_size, keys,
values);
cleanup:
free(keys);
free(values);
close(map_fd);
}
void test_map_batch_overflow(void)
{
if (test__start_subtest("array_lookup"))
test_array_batch_overflow(17, 1024U, TEST_BATCH_LOOKUP);
if (test__start_subtest("array_lookup_4gb_plus"))
test_array_batch_overflow(17, 0x10000000U, TEST_BATCH_LOOKUP);
if (test__start_subtest("array_update"))
test_array_batch_overflow(17, 1024U, TEST_BATCH_UPDATE);
if (test__start_subtest("array_update_4gb_plus"))
test_array_batch_overflow(17, 0x10000000U, TEST_BATCH_UPDATE);
}
```
The output of "sudo ./test_progs -t map_batch_overflow":
#212/1 map_batch_overflow/array_lookup:OK
validate_batch_lookup:PASS:map_lookup_batch 0 nsec
validate_batch_lookup:PASS:map_lookup_batch_count 0 nsec
validate_batch_lookup:FAIL:map_lookup_batch_value unexpected map_lookup_batch_value: actual 16 != expected 0
#212/2 map_batch_overflow/array_lookup_4gb_plus:FAIL
#212/3 map_batch_overflow/array_update:OK
validate_batch_update:PASS:map_update_batch 0 nsec
validate_batch_update:PASS:map_update_batch_count 0 nsec
validate_batch_update:PASS:map_update_batch_lookup 0 nsec
validate_batch_update:FAIL:map_update_batch_value unexpected map_update_batch_value: actual 0 != expected 16
#212/4 map_batch_overflow/array_update_4gb_plus:FAIL
#212 map_batch_overflow:FAIL
All error logs:
validate_batch_lookup:PASS:map_lookup_batch 0 nsec
validate_batch_lookup:PASS:map_lookup_batch_count 0 nsec
validate_batch_lookup:FAIL:map_lookup_batch_value unexpected map_lookup_batch_value: actual 16 != expected 0
#212/2 map_batch_overflow/array_lookup_4gb_plus:FAIL
validate_batch_update:PASS:map_update_batch 0 nsec
validate_batch_update:PASS:map_update_batch_count 0 nsec
validate_batch_update:PASS:map_update_batch_lookup 0 nsec
validate_batch_update:FAIL:map_update_batch_value unexpected map_update_batch_value: actual 0 != expected 16
#212/4 map_batch_overflow/array_update_4gb_plus:FAIL
#212 map_batch_overflow:FAIL
Summary: 0/2 PASSED, 0 SKIPPED, 1 FAILED
next prev parent reply other threads:[~2026-09-06 22:43 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-24 11:31 [PATCH] bpf: Fix u32 overflow issue in map batch operations Masoud Aghasi
2026-08-24 11:42 ` sashiko-bot
2026-08-25 10:21 ` Masoud Aghasi
2026-09-02 20:44 ` [PATCH v2] " Masoud Aghasi
2026-09-02 21:50 ` bot+bpf-ci
2026-09-03 8:27 ` [PATCH v3] " Masoud Aghasi
2026-09-03 8:45 ` sashiko-bot
2026-09-03 12:31 ` Masoud Aghasi
2026-09-04 4:45 ` Alexei Starovoitov
2026-09-04 13:19 ` Masoud Aghasi
2026-09-06 22:42 ` Masoud Aghasi [this message]
2026-09-06 23:34 ` Masoud Aghasi
2026-09-14 5:00 ` patchwork-bot+netdevbpf
2026-08-24 12:17 ` [PATCH] " bot+bpf-ci
2026-08-24 19:15 ` Masoud Aghasi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5574f80b-104c-48d7-8d1e-74b1cc720a41@disroot.org \
--to=maghasi@disroot.org \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=brianvv@google.com \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=ihor.solodrai@linux.dev \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.