Re: [PATCH bpf-next v4 5/8] bpf: Update per-CPU maps using BPF_F_ALL_CPUS flag

sashiko-bot
2026-04-14T21:02:35Z

Sashiko AI review found 1 potential issue(s):
- [High] The patch unconditionally forces the BPF_F_ALL_CPUS flag for any kernel-originated per-CPU map update that omits CPU flags, breaking the bpf_sys_bpf() helper API for BPF_PROG_TYPE_SYSCALL programs.
--

commit 357a4fab1d0fc8586bb52bd3aab10e26fd39a2a6
Author: Leon Hwang <leon.hwang@linux.dev>

bpf: Update per-CPU maps using BPF_F_ALL_CPUS flag

This commit modifies map_update_elem() to automatically apply the
BPF_F_ALL_CPUS flag for kernel-originated updates to per-CPU maps when no
CPU flags are specified. This is intended to fix potential out-of-bounds
reads when updating maps via the lightweight skeleton loader on systems where
the number of cached slots is less than the number of CPUs.

> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index b73b25c630734..f0f3785ef57d0 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -1785,6 +1785,21 @@ static int map_update_elem(union bpf_attr *attr, bpfptr_t uattr)
> goto err_put;
> }
>
> + /*
> + * When updating per-CPU maps via the lightweight skeleton
> + * loader, use a single value slot across all CPUs. This avoids
> + * two potential issues when updating on an M-CPU kernel with
> + * N cached slots (N < M), especially when N is much smaller
> + * than M:
> + * 1) The update may trigger a page fault when copying data from
> + * the last slot, as the read may go beyond the allocated
> + * buffer.
> + * 2) The update may copy unexpected data from slots [N, M-1].
> + */
> + if (bpfptr_is_kernel(uattr) && bpf_map_supports_cpu_flags(map->map_type) &&
> + !(attr->flags & (BPF_F_CPU | BPF_F_ALL_CPUS)))
> + attr->flags |= BPF_F_ALL_CPUS;

Does this unintentionally break the bpf_sys_bpf() helper API for
BPF_PROG_TYPE_SYSCALL programs?

Because bpf_sys_bpf() also wraps the pointer with KERNEL_BPFPTR,
bpfptr_is_kernel(uattr) will evaluate to true for any eBPF program calling it.

Prior to this patch, a BPF_PROG_TYPE_SYSCALL program could legitimately
update a per-CPU map with distinct values for each CPU by providing an array
of num_possible_cpus() elements and omitting any CPU flags, which mirrors
standard user-space API semantics.

With this change, it appears the kernel silently overrides attr->flags by
setting BPF_F_ALL_CPUS. This truncates the internal value_size calculation
down to a single element (map->value_size), reads only the first element
of the BPF program's provided buffer, and incorrectly replicates it across
all CPUs.

Should this workaround for the skeleton loader be constrained to
bpftool gen skeleton instead of mutating the core syscall handler?

--
Sashiko AI review · https://sashiko.dev/#/patchset/20260414132421.63409-1-leon.hwang@linux.dev?part=5