From: Mykyta Yatsenko <mykyta.yatsenko5@gmail.com>
To: Daniel Borkmann <daniel@iogearbox.net>, ast@kernel.org
Cc: memxor@gmail.com, eddyz87@gmail.com, info@starlabs.sg,
bpf@vger.kernel.org
Subject: Re: [PATCH bpf 1/4] bpf: Add KF_PERFMON kfunc flag
Date: Thu, 10 Sep 2026 16:03:42 +0100 [thread overview]
Message-ID: <ea68b32c-1af2-47ae-b168-4fd6791f607b@gmail.com> (raw)
In-Reply-To: <20260910142107.40582-1-daniel@iogearbox.net>
On 9/10/26 3:21 PM, Daniel Borkmann wrote:
> Tracing related BPF helpers e.g. under bpf_base_func_proto() are gated
> behind CAP_PERFMON. However, the same is currently not true for kfuncs
> and they are accessible via plain CAP_BPF. Add a new KF_PERFMON flag
> which can be used such that check_kfunc_call() ensures env->allow_ptr_leaks
> is permitted. This follows similar pattern to existing KF_DESTRUCTIVE flag.
>
This problem has been reported and patch sent some time ago:
https://lore.kernel.org/all/20260615-f01-07-dynptr-probe-read-cap-v1-0-e626cd61a381@mails.tsinghua.edu.cn/
> The rejection returns -EPERM to match the other CAP_PERFMON gates in the
> verifier, that is, check_ptr_to_btf_access() and check_ptr_to_map_access(),
> which report the very same policy to user space.
>
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> ---
> Documentation/bpf/kfuncs.rst | 10 ++++++++++
> include/linux/btf.h | 1 +
> kernel/bpf/verifier.c | 15 +++++++++++++++
> 3 files changed, 26 insertions(+)
>
> diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
> index 85f73e0bbd0f..6691fe8a32c3 100644
> --- a/Documentation/bpf/kfuncs.rst
> +++ b/Documentation/bpf/kfuncs.rst
> @@ -486,6 +486,16 @@ Example usage in BPF program:
> /* note that the last argument is omitted */
> bpf_task_work_schedule_signal(task, &work->tw, &arrmap, task_work_callback);
>
> +2.5.10 KF_PERFMON flag
> +----------------------
> +
> +The KF_PERFMON flag is used for kfuncs that can expose kernel memory or kernel
> +addresses to the BPF program, for example by reading through a pointer that the
> +verifier does not check. Calling such a kfunc requires CAP_PERFMON, or
> +CAP_SYS_ADMIN, in the same way that the equivalent BPF helpers are gated in
> +bpf_base_func_proto(). A program loaded with CAP_BPF alone is rejected at load
> +time.
> +
> 2.6 Registering the kfuncs
> --------------------------
>
> diff --git a/include/linux/btf.h b/include/linux/btf.h
> index 89d5a5c4f117..7c62ea17b116 100644
> --- a/include/linux/btf.h
> +++ b/include/linux/btf.h
> @@ -80,6 +80,7 @@
> #define KF_ARENA_ARG2 (1 << 15) /* kfunc takes an arena pointer as its second argument */
> #define KF_IMPLICIT_ARGS (1 << 16) /* kfunc has implicit arguments supplied by the verifier */
> #define KF_SPINLOCK_SAFE (1 << 17) /* kfunc is allowed inside bpf_spin_lock-ed region */
> +#define KF_PERFMON (1 << 18) /* kfunc requires CAP_PERFMON */
>
> /*
> * Tag marking a kernel function as a kfunc. This is meant to minimize the
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 45234e2fbee6..5d61e74865a8 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -11356,6 +11356,11 @@ static bool is_kfunc_destructive(struct bpf_call_arg_meta *meta)
> return meta->kfunc_flags & KF_DESTRUCTIVE;
> }
>
> +static bool is_kfunc_perfmon(struct bpf_call_arg_meta *meta)
> +{
> + return meta->kfunc_flags & KF_PERFMON;
> +}
> +
> static bool is_kfunc_rcu(struct bpf_call_arg_meta *meta)
> {
> return meta->kfunc_flags & KF_RCU;
> @@ -13834,6 +13839,16 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
> return -EACCES;
> }
>
> + if (is_kfunc_perfmon(&meta) && !env->allow_ptr_leaks) {
> + verbose(env, "%s is allowed only to CAP_PERFMON and CAP_SYS_ADMIN\n",
> + func_name);
> + operation = bpf_diag_fmt(env, "kfunc %s", func_name);
> + bpf_diag_policy(
> + env, insn_idx, operation, "the kfunc requires CAP_PERFMON",
> + "Load the program with CAP_PERFMON, or avoid the kfunc.");
> + return -EPERM;
> + }
> +
> 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);
next prev parent reply other threads:[~2026-09-10 15:03 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-10 14:21 [PATCH bpf 1/4] bpf: Add KF_PERFMON kfunc flag Daniel Borkmann
2026-09-10 14:21 ` [PATCH bpf 2/4] bpf: Require CAP_PERFMON for kfuncs reading memory Daniel Borkmann
2026-09-10 15:10 ` bot+bpf-ci
2026-09-10 15:41 ` Alexei Starovoitov
2026-09-10 15:53 ` Daniel Borkmann
2026-09-10 14:21 ` [PATCH bpf 3/4] bpf: Require CAP_PERFMON for untrusted read-only memory reads Daniel Borkmann
2026-09-10 15:42 ` Alexei Starovoitov
2026-09-10 14:21 ` [PATCH bpf 4/4] selftests/bpf: Add tests for the KF_PERFMON gates Daniel Borkmann
2026-09-10 15:03 ` Mykyta Yatsenko [this message]
2026-09-10 15:14 ` [PATCH bpf 1/4] bpf: Add KF_PERFMON kfunc flag Kumar Kartikeya Dwivedi
2026-09-10 15:21 ` Mykyta Yatsenko
2026-09-10 15:10 ` bot+bpf-ci
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=ea68b32c-1af2-47ae-b168-4fd6791f607b@gmail.com \
--to=mykyta.yatsenko5@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=info@starlabs.sg \
--cc=memxor@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox