All of lore.kernel.org
 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 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.