BPF List
 help / color / mirror / Atom feed
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


  parent reply	other threads:[~2026-09-06 22:43 UTC|newest]

Thread overview: 14+ 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-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox