* [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
* 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
* [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
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