Commit bbc1d247 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov
Browse files

bpf: Take into account BPF token when fetching helper protos



Instead of performing unconditional system-wide bpf_capable() and
perfmon_capable() calls inside bpf_base_func_proto() function (and other
similar ones) to determine eligibility of a given BPF helper for a given
program, use previously recorded BPF token during BPF_PROG_LOAD command
handling to inform the decision.

Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20240124022127.2379740-8-andrii@kernel.org
parent caf8f28e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ lirc_mode2_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
	case BPF_FUNC_get_prandom_u32:
		return &bpf_get_prandom_u32_proto;
	case BPF_FUNC_trace_printk:
		if (perfmon_capable())
		if (bpf_token_capable(prog->aux->token, CAP_PERFMON))
			return bpf_get_trace_printk_proto();
		fallthrough;
	default:
+3 −2
Original line number Diff line number Diff line
@@ -2550,7 +2550,8 @@ int btf_find_next_decl_tag(const struct btf *btf, const struct btf_type *pt,
struct bpf_prog *bpf_prog_by_id(u32 id);
struct bpf_link *bpf_link_by_id(u32 id);

const struct bpf_func_proto *bpf_base_func_proto(enum bpf_func_id func_id);
const struct bpf_func_proto *bpf_base_func_proto(enum bpf_func_id func_id,
						 const struct bpf_prog *prog);
void bpf_task_storage_free(struct task_struct *task);
void bpf_cgrp_storage_free(struct cgroup *cgroup);
bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog);
@@ -2810,7 +2811,7 @@ static inline int btf_struct_access(struct bpf_verifier_log *log,
}

static inline const struct bpf_func_proto *
bpf_base_func_proto(enum bpf_func_id func_id)
bpf_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
	return NULL;
}
+3 −3
Original line number Diff line number Diff line
@@ -1630,7 +1630,7 @@ cgroup_dev_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
	case BPF_FUNC_perf_event_output:
		return &bpf_event_output_data_proto;
	default:
		return bpf_base_func_proto(func_id);
		return bpf_base_func_proto(func_id, prog);
	}
}

@@ -2191,7 +2191,7 @@ sysctl_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
	case BPF_FUNC_perf_event_output:
		return &bpf_event_output_data_proto;
	default:
		return bpf_base_func_proto(func_id);
		return bpf_base_func_proto(func_id, prog);
	}
}

@@ -2348,7 +2348,7 @@ cg_sockopt_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
	case BPF_FUNC_perf_event_output:
		return &bpf_event_output_data_proto;
	default:
		return bpf_base_func_proto(func_id);
		return bpf_base_func_proto(func_id, prog);
	}
}

+3 −3
Original line number Diff line number Diff line
@@ -1680,7 +1680,7 @@ const struct bpf_func_proto bpf_probe_read_kernel_str_proto __weak;
const struct bpf_func_proto bpf_task_pt_regs_proto __weak;

const struct bpf_func_proto *
bpf_base_func_proto(enum bpf_func_id func_id)
bpf_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
	switch (func_id) {
	case BPF_FUNC_map_lookup_elem:
@@ -1731,7 +1731,7 @@ bpf_base_func_proto(enum bpf_func_id func_id)
		break;
	}

	if (!bpf_capable())
	if (!bpf_token_capable(prog->aux->token, CAP_BPF))
		return NULL;

	switch (func_id) {
@@ -1789,7 +1789,7 @@ bpf_base_func_proto(enum bpf_func_id func_id)
		break;
	}

	if (!perfmon_capable())
	if (!bpf_token_capable(prog->aux->token, CAP_PERFMON))
		return NULL;

	switch (func_id) {
+3 −2
Original line number Diff line number Diff line
@@ -5772,7 +5772,7 @@ static const struct bpf_func_proto bpf_sys_bpf_proto = {
const struct bpf_func_proto * __weak
tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
	return bpf_base_func_proto(func_id);
	return bpf_base_func_proto(func_id, prog);
}

BPF_CALL_1(bpf_sys_close, u32, fd)
@@ -5822,7 +5822,8 @@ syscall_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
	switch (func_id) {
	case BPF_FUNC_sys_bpf:
		return !perfmon_capable() ? NULL : &bpf_sys_bpf_proto;
		return !bpf_token_capable(prog->aux->token, CAP_PERFMON)
		       ? NULL : &bpf_sys_bpf_proto;
	case BPF_FUNC_btf_find_by_name_kind:
		return &bpf_btf_find_by_name_kind_proto;
	case BPF_FUNC_sys_close:
Loading