BPF List
 help / color / mirror / Atom feed
* [PATCH 0/2] bpf: Fix incorrect handling of user flags by percpu map updates
@ 2026-09-28 10:28 Masoud Aghasi
  2026-09-28 10:28 ` [PATCH 1/2] " Masoud Aghasi
  2026-09-28 10:28 ` [PATCH 2/2] selftests/bpf: add test for percpu map flags combination Masoud Aghasi
  0 siblings, 2 replies; 5+ messages in thread
From: Masoud Aghasi @ 2026-09-28 10:28 UTC (permalink / raw)
  To: bpf
  Cc: andrii, eddyz87, ast, daniel, memxor, martin.lau, song,
	yonghong.song, jolsa, emil, ihor.solodrai, leon.hwang,
	Masoud Aghasi

For BPF_MAP_TYPE_PERCPU_HASH map, htab_map_check_update_flags() and
check_flags() are not considering the possibility of a combination of
(BPF_NOEXIST, BPF_EXIST) flags with (BPF_F_CPU, BPF_F_ALL_CPUS) flags.
This causes the (BPF_NOEXIST, BPF_EXIST) flags to lose their effect.

For example, when using (BPF_F_CPU | BPF_EXIST) flag combination
with bpf_map_update_elem() on a BPF_MAP_TYPE_PERCPU_HASH map, the
BPF_EXIST flag does not prevent new insertions as expected.

Also for BPF_MAP_TYPE_PERCPU_ARRAY map, using the (BPF_F_ALL_CPUS |
BPF_EXIST) flag combination with bpf_map_update_elem() results in an
incorrect EINVAL error response, even though the flag combination is
valid. 

This series fixes the bug by adding proper flag validations and checks
and adds a regression test.

Masoud Aghasi (2):
  bpf: Fix incorrect handling of user flags by percpu map updates
  selftests/bpf: add test for percpu map flags combination

 kernel/bpf/arraymap.c                         |  4 ++--
 kernel/bpf/hashtab.c                          |  9 ++++++---
 .../selftests/bpf/prog_tests/percpu_alloc.c   | 20 +++++++++++++++++++
 3 files changed, 28 insertions(+), 5 deletions(-)

-- 
2.47.3


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] bpf: Fix incorrect handling of user flags by percpu map updates
  2026-09-28 10:28 [PATCH 0/2] bpf: Fix incorrect handling of user flags by percpu map updates Masoud Aghasi
@ 2026-09-28 10:28 ` Masoud Aghasi
  2026-09-28 10:41   ` sashiko-bot
  2026-09-28 10:28 ` [PATCH 2/2] selftests/bpf: add test for percpu map flags combination Masoud Aghasi
  1 sibling, 1 reply; 5+ messages in thread
From: Masoud Aghasi @ 2026-09-28 10:28 UTC (permalink / raw)
  To: bpf
  Cc: andrii, eddyz87, ast, daniel, memxor, martin.lau, song,
	yonghong.song, jolsa, emil, ihor.solodrai, leon.hwang,
	Masoud Aghasi

For BPF_MAP_TYPE_PERCPU_HASH map, htab_map_check_update_flags() and
check_flags() are not considering the possibility of a combination of
(BPF_NOEXIST, BPF_EXIST) flags with (BPF_F_CPU, BPF_F_ALL_CPUS) flags.
This causes the (BPF_NOEXIST, BPF_EXIST) flags to lose their effect.

For example, when using (BPF_F_CPU | BPF_EXIST) flag combination
with bpf_map_update_elem() on a BPF_MAP_TYPE_PERCPU_HASH map, the
BPF_EXIST flag does not prevent new insertions as expected.

Also for BPF_MAP_TYPE_PERCPU_ARRAY map, using the (BPF_F_ALL_CPUS |
BPF_EXIST) flag combination with bpf_map_update_elem() results in an
incorrect EINVAL error response, even though the flag combination is
valid.

This patch fixes the bug by adding proper flag validations and checks.

Fixes: c6936161fd55 ("bpf: Add BPF_F_CPU and BPF_F_ALL_CPUS flags support for percpu_hash and lru_percpu_hash maps")
Fixes: 8eb76cb03f0f ("bpf: Add BPF_F_CPU and BPF_F_ALL_CPUS flags support for percpu_array maps")
Signed-off-by: Masoud Aghasi <maghasi@disroot.org>
---
 kernel/bpf/arraymap.c | 4 ++--
 kernel/bpf/hashtab.c  | 9 ++++++---
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 0fe9afd4a591..1be86e9b2e84 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -438,7 +438,7 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
 	u32 size;
 	int cpu, off = 0;
 
-	if (unlikely((map_flags & BPF_F_LOCK) || (u32)map_flags > BPF_F_ALL_CPUS))
+	if (unlikely((u32)map_flags & ~(BPF_EXIST | BPF_NOEXIST | BPF_F_CPU | BPF_F_ALL_CPUS)))
 		/* unknown flags */
 		return -EINVAL;
 
@@ -446,7 +446,7 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
 		/* all elements were pre-allocated, cannot insert a new one */
 		return -E2BIG;
 
-	if (unlikely(map_flags == BPF_NOEXIST))
+	if (unlikely(map_flags & BPF_NOEXIST))
 		/* all elements already exist */
 		return -EEXIST;
 
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 53c99fe4f176..648b9aeb917c 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -1196,11 +1196,11 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key,
 static int check_flags(struct bpf_htab *htab, struct htab_elem *l_old,
 		       u64 map_flags)
 {
-	if (l_old && (map_flags & ~BPF_F_LOCK) == BPF_NOEXIST)
+	if (l_old && (map_flags & BPF_NOEXIST))
 		/* elem already exists */
 		return -EEXIST;
 
-	if (!l_old && (map_flags & ~BPF_F_LOCK) == BPF_EXIST)
+	if (!l_old && (map_flags & BPF_EXIST))
 		/* elem doesn't exist, cannot update it */
 		return -ENOENT;
 
@@ -1383,9 +1383,12 @@ static long htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value
 
 static int htab_map_check_update_flags(bool onallcpus, u64 map_flags)
 {
+	if (unlikely((map_flags & BPF_EXIST) && (map_flags & BPF_NOEXIST)))
+		return -EINVAL;
 	if (unlikely(!onallcpus && map_flags > BPF_EXIST))
 		return -EINVAL;
-	if (unlikely(onallcpus && ((map_flags & BPF_F_LOCK) || (u32)map_flags > BPF_F_ALL_CPUS)))
+	if (unlikely(onallcpus &&
+	    ((u32)map_flags & ~(BPF_EXIST | BPF_NOEXIST | BPF_F_CPU | BPF_F_ALL_CPUS))))
 		return -EINVAL;
 	return 0;
 }
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] selftests/bpf: add test for percpu map flags combination
  2026-09-28 10:28 [PATCH 0/2] bpf: Fix incorrect handling of user flags by percpu map updates Masoud Aghasi
  2026-09-28 10:28 ` [PATCH 1/2] " Masoud Aghasi
@ 2026-09-28 10:28 ` Masoud Aghasi
  1 sibling, 0 replies; 5+ messages in thread
From: Masoud Aghasi @ 2026-09-28 10:28 UTC (permalink / raw)
  To: bpf
  Cc: andrii, eddyz87, ast, daniel, memxor, martin.lau, song,
	yonghong.song, jolsa, emil, ihor.solodrai, leon.hwang,
	Masoud Aghasi

Add a test that exercises using a combination of flags for
percpu map update.

Before the fix, this test fails to respect user flags combination of
(BPF_F_CPU | BPF_EXIST). With the fix applied the test passes.

Signed-off-by: Masoud Aghasi <maghasi@disroot.org>
---
 .../selftests/bpf/prog_tests/percpu_alloc.c   | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/percpu_alloc.c b/tools/testing/selftests/bpf/prog_tests/percpu_alloc.c
index 7b4a1e24363b..a0a1fa0e11c0 100644
--- a/tools/testing/selftests/bpf/prog_tests/percpu_alloc.c
+++ b/tools/testing/selftests/bpf/prog_tests/percpu_alloc.c
@@ -537,6 +537,24 @@ static void test_hash_cpu_flag(void)
 	test_map_op_cpu_flag(BPF_MAP_TYPE_HASH);
 }
 
+static void test_percpu_hash_flags_combination(void)
+{
+	u32 max_entries = 1;
+	u64 flags, val = 0;
+	int err, map_fd, key = 0;
+
+	map_fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_HASH, "test_flags_combo",
+				sizeof(int), sizeof(u64), max_entries, NULL);
+	if (!ASSERT_GE(map_fd, 0, "bpf_map_create"))
+		return;
+
+	flags = BPF_F_CPU | BPF_EXIST;
+	err = bpf_map_update_elem(map_fd, &key, &val, flags);
+	ASSERT_EQ(err, -ENOENT, "bpf_map_update_elem flags_combo");
+
+	close(map_fd);
+}
+
 void test_percpu_alloc(void)
 {
 	if (test__start_subtest("array"))
@@ -565,4 +583,6 @@ void test_percpu_alloc(void)
 		test_array_cpu_flag();
 	if (test__start_subtest("cpu_flag_hash"))
 		test_hash_cpu_flag();
+	if (test__start_subtest("percpu_hash_flags_combination"))
+		test_percpu_hash_flags_combination();
 }
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] bpf: Fix incorrect handling of user flags by percpu map updates
  2026-09-28 10:28 ` [PATCH 1/2] " Masoud Aghasi
@ 2026-09-28 10:41   ` sashiko-bot
  2026-09-28 12:53     ` Masoud Aghasi
  0 siblings, 1 reply; 5+ messages in thread
From: sashiko-bot @ 2026-09-28 10:41 UTC (permalink / raw)
  To: Masoud Aghasi; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] bpf: bpf_percpu_array_update() misses validation for mutually exclusive flags
--

commit 41d85d3576867a24ad9b52f72cd4c1d7b23504a6
Author: Masoud Aghasi <maghasi@disroot.org>

bpf: Fix incorrect handling of user flags by percpu map updates

This commit fixes incorrect handling of BPF_EXIST, BPF_NOEXIST, BPF_F_CPU,
and BPF_F_ALL_CPUS flag combinations in BPF_MAP_TYPE_PERCPU_HASH and
BPF_MAP_TYPE_PERCPU_ARRAY map updates.

> diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
> index 0ce26b538075e..463f43b19e5cd 100644
> --- a/kernel/bpf/arraymap.c
> +++ b/kernel/bpf/arraymap.c
> @@ -438,7 +438,7 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
>  	u32 size;
>  	int cpu, off = 0;
>  
> -	if (unlikely((map_flags & BPF_F_LOCK) || (u32)map_flags > BPF_F_ALL_CPUS))
> +	if (unlikely((u32)map_flags & ~(BPF_EXIST | BPF_NOEXIST | BPF_F_CPU | BPF_F_ALL_CPUS)))
>  		/* unknown flags */
>  		return -EINVAL;
>  
> @@ -446,7 +446,7 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
>  		/* all elements were pre-allocated, cannot insert a new one */
>  		return -E2BIG;
>  
> -	if (unlikely(map_flags == BPF_NOEXIST))
> +	if (unlikely(map_flags & BPF_NOEXIST))

[Severity: Low]
Does this validation correctly handle the case where both BPF_EXIST and
BPF_NOEXIST are passed together?

Since the mask check above allows this mutually exclusive combination through,
evaluating `map_flags & BPF_NOEXIST` as true here will return -EEXIST instead
of the expected -EINVAL error code. Should an explicit check for the 
combination of BPF_EXIST and BPF_NOEXIST be added here, similar to the one
added for hash maps in htab_map_check_update_flags() in this same patch?

>  		/* all elements already exist */
>  		return -EEXIST;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260928102821.995214-1-maghasi@disroot.org?part=1

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] bpf: Fix incorrect handling of user flags by percpu map updates
  2026-09-28 10:41   ` sashiko-bot
@ 2026-09-28 12:53     ` Masoud Aghasi
  0 siblings, 0 replies; 5+ messages in thread
From: Masoud Aghasi @ 2026-09-28 12:53 UTC (permalink / raw)
  To: bpf
  Cc: andrii, eddyz87, ast, daniel, memxor, martin.lau, song,
	yonghong.song, jolsa, emil, ihor.solodrai, leon.hwang,
	sashiko-reviews

On 28/09/2026 11:41, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Low] bpf: bpf_percpu_array_update() misses validation for mutually exclusive flags
> --
> 
> commit 41d85d3576867a24ad9b52f72cd4c1d7b23504a6
> Author: Masoud Aghasi <maghasi@disroot.org>
> 
> bpf: Fix incorrect handling of user flags by percpu map updates
> 
> This commit fixes incorrect handling of BPF_EXIST, BPF_NOEXIST, BPF_F_CPU,
> and BPF_F_ALL_CPUS flag combinations in BPF_MAP_TYPE_PERCPU_HASH and
> BPF_MAP_TYPE_PERCPU_ARRAY map updates.
> 
>> diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
>> index 0ce26b538075e..463f43b19e5cd 100644
>> --- a/kernel/bpf/arraymap.c
>> +++ b/kernel/bpf/arraymap.c
>> @@ -438,7 +438,7 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
>>  	u32 size;
>>  	int cpu, off = 0;
>>  
>> -	if (unlikely((map_flags & BPF_F_LOCK) || (u32)map_flags > BPF_F_ALL_CPUS))
>> +	if (unlikely((u32)map_flags & ~(BPF_EXIST | BPF_NOEXIST | BPF_F_CPU | BPF_F_ALL_CPUS)))
>>  		/* unknown flags */
>>  		return -EINVAL;
>>  
>> @@ -446,7 +446,7 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
>>  		/* all elements were pre-allocated, cannot insert a new one */
>>  		return -E2BIG;
>>  
>> -	if (unlikely(map_flags == BPF_NOEXIST))
>> +	if (unlikely(map_flags & BPF_NOEXIST))
> 
> [Severity: Low]
> Does this validation correctly handle the case where both BPF_EXIST and
> BPF_NOEXIST are passed together?
> 
> Since the mask check above allows this mutually exclusive combination through,
> evaluating `map_flags & BPF_NOEXIST` as true here will return -EEXIST instead
> of the expected -EINVAL error code. Should an explicit check for the 
> combination of BPF_EXIST and BPF_NOEXIST be added here, similar to the one
> added for hash maps in htab_map_check_update_flags() in this same patch?
> 
>>  		/* all elements already exist */
>>  		return -EEXIST;
> 

As there is already a check for "BPF_NOEXIST", it is just a matter of
which error code to return, -EEXIST or -EINVAL. The implementation
currently handles it by prioritizing the BPF_NOEXIST.

There is a similar case for the combination of BPF_F_CPU and
BPF_F_ALL_CPUS, but the implementation already handles it by
prioritizing the BPF_F_CPU.

But let's wait for other reviews as well.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-09-28 12:54 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-28 10:28 [PATCH 0/2] bpf: Fix incorrect handling of user flags by percpu map updates Masoud Aghasi
2026-09-28 10:28 ` [PATCH 1/2] " Masoud Aghasi
2026-09-28 10:41   ` sashiko-bot
2026-09-28 12:53     ` Masoud Aghasi
2026-09-28 10:28 ` [PATCH 2/2] selftests/bpf: add test for percpu map flags combination Masoud Aghasi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox