mirror of
https://github.com/torvalds/linux.git
synced 2026-09-29 04:22:03 +02:00
bpf: Add KF_PERFMON kfunc flag
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. 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> Link: https://lore.kernel.org/r/20260910213510.49358-1-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
e4a62833ad
commit
88ce88e933
|
|
@ -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
|
||||
--------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,15 @@ 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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user