Re: [PATCH bpf-next v5 12/14] bpf: Report Execution Context Safety errors

[email protected]
Newsgroups org.kernel.vger.bpf
Message-ID <2e42a1a2bf45f4d2aba7495bdc9f147558055740e2f3c8b9dae255f6c57fc13c@mail.kernel.org>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 2c067be53106..a81a7ed18d76 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c

[ ... ]

> @@ -13657,6 +13682,9 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
>  	sleepable = bpf_is_kfunc_sleepable(&meta);
>  	if (sleepable && !in_sleepable(env)) {
>  		verbose(env, "program must be sleepable to call sleepable kfunc %s\n", func_name);
> +		operation = bpf_diag_fmt(env, "sleepable kfunc %s", func_name);
> +		bpf_diag_ctx_forbidden(env, insn_idx, operation,
> +			"Mark the program sleepable if the program type allows it, or use a non-sleepable kfunc.");
>  		return -EACCES;
>  	}

Can this diagnostic produce contradictory output when a non-sleepable
program happens to be inside a critical section?

The rejection condition is !in_sleepable(env), which tests whether the
program itself is sleepable (env->cur_state->in_sleepable), not whether
the current path is in a sleepable context.

But bpf_diag_ctx_forbidden() derives the context kind from cur_state by
checking active_rcu_locks, active_preempt_locks, active_irq_id, and
active_locks in that order (kernel/bpf/diagnostics.c:1084-1093).

When a non-sleepable XDP program calls bpf_rcu_read_lock() (which is
registered without restrictions in kernel/bpf/helpers.c:4887) and then
attempts to call a KF_SLEEPABLE kfunc like bpf_copy_from_user_str, the
path reaches this branch with active_rcu_locks == 1, so the diagnostic
reports:

  Reason: The operation sleepable kfunc bpf_copy_from_user_str cannot
  be used in RCU read lock region because RCU read-side critical
  sections cannot call operations that may sleep. This path is still
  inside an active RCU read lock region (depth 1).

  Suggestion: Mark the program sleepable if the program type allows it,
  or use a non-sleepable kfunc.

The verbose() line says the program must be sleepable, the Reason blames
the RCU region, and the Suggestion says to mark the program sleepable.
These point at different fixes.

Leaving the RCU region as the Reason implies does not clear the
rejection, and marking the program sleepable as suggested does not
remove the reported Reason either (the call would then hit the
!in_sleepable_context check at line 13787 instead).

The other three bpf_diag_ctx_forbidden() call sites added in this patch
(line 9860 in check_func_call, 10768 in check_helper_call, 13787 in
check_kfunc_call) are all gated on !in_sleepable_context(env) and their
verbose() lines call non_sleepable_context_description(env), so their
diagnostics are self-consistent with the rejection reason.

Would it make sense to pass BPF_DIAG_CONTEXT_NONE explicitly at this
site, or to have bpf_diag_ctx_forbidden() take a context kind parameter?
That way diag_context_name(BPF_DIAG_CONTEXT_NONE) would return
"non-sleepable program" and produce the accurate "cannot be used in
non-sleepable program" report that matches the actual failure condition.


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/31870608176
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.