All of lore.kernel.org
 help / color / mirror / Atom feed
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);


  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 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.