From: sashiko-bot@kernel.org
To: "Alexei Starovoitov" <alexei.starovoitov@gmail.com>, bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next 23/38] bpf: Check the maps that sleepable callbacks use
Date: Sat, 17 Oct 2026 01:58:01 +0000 [thread overview]
Message-ID: <sashiko-outbox-175168@kernel.org> (raw)
In-Reply-To: <20261017012451.364800-15-alexei.starovoitov@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] bpf: global subprog call under preempt/irq disable bypasses map RCU check
--
commit 44c0901fdd3a21bde77f64657ef1a8f91005cd05
Author: Josef Bacik <josef@toxicpanda.com>
bpf: Check the maps that sleepable callbacks use
This commit restricts map helper calls in sleepable contexts (such as bpf_wq
or bpf_task_work callbacks, or with inner maps) to maps that do not require an
RCU read-side lock unless bpf_rcu_read_lock() is held or the helper runs inside
an RCU callback. It also adds bloom filters to the list of maps usable without
RCU.
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 1f2a846ae415f..09173d1d66d39 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
[ ... ]
> @@ -10379,12 +10380,57 @@ bool bpf_allow_tail_call_in_subprogs(struct bpf_verifier_env *env)
> bpf_jit_supports_subprog_tailcalls();
> }
>
> +/* May the map be used outside of an RCU read side critical section? */
> +static bool map_needs_no_rcu(const struct bpf_map *map)
> +{
[ ... ]
> +}
> +
> static int check_map_func_compatibility(struct bpf_verifier_env *env,
> struct bpf_map *map, int func_id)
> {
> if (!map)
> return 0;
>
> + /*
> + * check_map_prog_compatibility() asks the program. That misses the
> + * sleepable callback of another program, and an inner map. They may
> + * use any map under the RCU read lock. Disabled preemption or
> + * interrupts will not do: the maps ask for rcu_read_lock_held().
> + */
> + if (in_sleepable(env) && !env->cur_state->active_rcu_locks &&
> + !in_rcu_callback(env) && !map_needs_no_rcu(map)) {
> + verbose(env, "map '%s' needs bpf_rcu_read_lock() in sleepable context\n",
> + map->name);
> + return -EINVAL;
> + }
[Severity: High]
Can this check be bypassed if a sleepable callback or sleepable program
disables preemption or local IRQs and then calls a global subprogram that
accesses the map?
When a global subprogram is called in check_func_call(), the verifier records
the calling context using in_sleepable_context(env):
kernel/bpf/verifier.c:check_func_call() {
...
if (sub_aux->func_info_aux == BPF_FUNC_GLOBAL) {
...
sub_aux->called[in_sleepable_context(env)] = true;
...
}
}
However, in_sleepable_context() checks in_rcu_cs(), which treats disabled
preemption (active_preempt_locks) and disabled local IRQs (active_irq_id) as an
RCU critical section even when active_rcu_locks is zero:
kernel/bpf/verifier.c:in_rcu_cs() {
return env->cur_state->active_rcu_locks ||
env->cur_state->active_preempt_locks ||
env->cur_state->active_locks ||
env->cur_state->active_irq_id ||
!in_sleepable(env);
}
kernel/bpf/verifier.c:in_sleepable_context() {
return !in_rcu_cs(env) && !in_rcu_callback(env);
}
If a bpf_wq or bpf_task_work callback calls bpf_preempt_disable() or
bpf_local_irq_save() without bpf_rcu_read_lock() and then calls a global
subprogram, in_sleepable_context(env) returns false and sets
sub_aux->called[0] = true.
When do_check_subprogs() later verifies that global subprogram via
do_check_common(env, i, 0), state->in_sleepable is initialized to false. Inside
the global subprogram, in_sleepable(env) evaluates to false in
check_map_func_compatibility(), allowing helpers such as bpf_map_lookup_elem()
on a sockhash or an inner RCU-requiring map without holding rcu_read_lock() and
triggering the WARN_ON_ONCE(!rcu_read_lock_held()) in __sock_hash_lookup_elem()
at runtime.
[ ... ]
>
>
>
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261017012058.355787-1-alexei.starovoitov@gmail.com?part=23
next prev parent reply other threads:[~2026-10-17 1:58 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 1:20 [PATCH bpf-next 00/38] bpf: Memory safety, lifetime and locking fixes Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 01/38] bpf: use the frame mem type in devmap egress XDP Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 02/38] bpf: forbid sleeping in hash map for_each callbacks Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 03/38] bpf: don't leak the inode when token creation fails Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 04/38] bpf: don't hand out a linked element as extra element Alexei Starovoitov
2026-10-17 1:45 ` sashiko-bot
2026-10-17 1:52 ` bot+bpf-ci
2026-10-17 1:20 ` [PATCH bpf-next 05/38] bpf: reject sleepable programs for task_vma iterator Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 06/38] bpf: forbid sleeping in bpf_find_vma() callbacks Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 07/38] bpf: look at all 64 bits of a BPF_JSET mask on 32-bit Alexei Starovoitov
2026-10-17 1:20 ` [PATCH bpf-next 08/38] bpf: don't let bpf_skb_adjust_room() use up the MSS Alexei Starovoitov
2026-10-17 1:51 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 09/38] bpf: Read the probe of a perf event under event_mutex Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 10/38] bpf: Don't saturate owner_refcnt on the last unpin Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 11/38] bpf: Validate the SRH which End.DT6 uncovers in End.BPF Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 12/38] bpf: Pull the inner header for End.DT6 " Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 13/38] bpf: Update the SRH state if End.B6 fails late Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 14/38] bpf: Clear sk_refcnt of a clone before its storage is linked Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 15/38] bpf: Fix NULL deref in the sk_storage map iterator Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 16/38] bpf: Hold the socket " Alexei Starovoitov
2026-10-17 2:02 ` bot+bpf-ci
2026-10-17 1:24 ` [PATCH bpf-next 17/38] bpf: Bound the nesting that the BTF show code follows Alexei Starovoitov
2026-10-17 1:46 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 18/38] bpf: Check the new program of an iterator link update Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 19/38] bpf: Fix stale offload->prog pointer after realloc Alexei Starovoitov
2026-10-17 1:45 ` sashiko-bot
2026-10-17 1:52 ` bot+bpf-ci
2026-10-17 1:24 ` [PATCH bpf-next 20/38] bpf: Don't bind a program to a netdev that goes away Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 21/38] bpf: Keep a program until its bpf_wq callback has ended Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 22/38] bpf: Count sleepable callbacks as sleepable map users Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 23/38] bpf: Check the maps that sleepable callbacks use Alexei Starovoitov
2026-10-17 1:58 ` sashiko-bot [this message]
2026-10-17 1:24 ` [PATCH bpf-next 24/38] bpf: Assume no bounds for buffers behind a tail call Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 25/38] bpf: Don't take an extension for an iterator program Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 26/38] bpf: Assume no bounds for a writable tp with tail calls Alexei Starovoitov
2026-10-17 2:05 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 27/38] bpf: Keep iterator programs off special map fields Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 28/38] bpf: Free what map_free() unlinks for sleepable readers Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 29/38] bpf: Keep values of a dead owner for sleepable programs Alexei Starovoitov
2026-10-17 2:10 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 30/38] bpf: Keep the symbols of a program until it has ended Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 31/38] bpf: Use the socket of a sk_lookup test run under RCU Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 32/38] bpf, cpumap: Hold the device of frames in the queue Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 33/38] bpf: Drop packet pointers behind kfuncs writing an skb Alexei Starovoitov
2026-10-17 2:10 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 34/38] bpf: Let bpf_dynptr_write() mark a global function Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 35/38] bpf: Don't take a dynptr argument for a local dynptr Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 36/38] bpf: Follow the head if an skb is written from a slice Alexei Starovoitov
2026-10-17 2:05 ` sashiko-bot
2026-10-17 1:24 ` [PATCH bpf-next 37/38] bpf: Use memmove() to store bytes in an skb Alexei Starovoitov
2026-10-17 1:24 ` [PATCH bpf-next 38/38] bpf: Refuse packet slices for packet-changing helpers Alexei Starovoitov
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=sashiko-outbox-175168@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=alexei.starovoitov@gmail.com \
--cc=bpf@vger.kernel.org \
--cc=sashiko-reviews@lists.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 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.