Abstract out two functions to check whether a particular helper is sleepable or not for bpf_lsm and bpf_trace. These two functions will be used later to check whether a helper is sleepable or not in verifier. There is no functionality change. Signed-off-by: Yonghong Song <yhs@xxxxxx> --- include/linux/bpf_lsm.h | 6 ++++++ include/linux/trace_events.h | 8 ++++++++ kernel/bpf/bpf_lsm.c | 20 ++++++++++++++++---- kernel/trace/bpf_trace.c | 22 ++++++++++++++++++---- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h index 4bcf76a9bb06..d99b1caf118e 100644 --- a/include/linux/bpf_lsm.h +++ b/include/linux/bpf_lsm.h @@ -28,6 +28,7 @@ int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog, const struct bpf_prog *prog); bool bpf_lsm_is_sleepable_hook(u32 btf_id); +const struct bpf_func_proto *bpf_lsm_sleepable_func_proto(enum bpf_func_id func_id); static inline struct bpf_storage_blob *bpf_inode( const struct inode *inode) @@ -50,6 +51,11 @@ static inline bool bpf_lsm_is_sleepable_hook(u32 btf_id) { return false; } +static inline const struct bpf_func_proto * +bpf_lsm_sleepable_func_proto(enum bpf_func_id func_id) +{ + return NULL; +} static inline int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog, const struct bpf_prog *prog) diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 20749bd9db71..c3eb4fb78ea5 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -9,6 +9,7 @@ #include <linux/hardirq.h> #include <linux/perf_event.h> #include <linux/tracepoint.h> +#include <uapi/linux/bpf.h> struct trace_array; struct array_buffer; @@ -16,6 +17,7 @@ struct tracer; struct dentry; struct bpf_prog; union bpf_attr; +struct bpf_func_proto; const char *trace_print_flags_seq(struct trace_seq *p, const char *delim, unsigned long flags, @@ -748,6 +750,7 @@ int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id, u32 *fd_type, const char **buf, u64 *probe_offset, u64 *probe_addr); int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog); +const struct bpf_func_proto *bpf_tracing_sleepable_func_proto(enum bpf_func_id func_id); #else static inline unsigned int trace_call_bpf(struct trace_event_call *call, void *ctx) { @@ -794,6 +797,11 @@ bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) { return -EOPNOTSUPP; } +static inline const struct bpf_func_proto * +bpf_tracing_sleepable_func_proto(enum bpf_func_id func_id) +{ + return NULL; +} #endif enum { diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c index d6c9b3705f24..2f993a003389 100644 --- a/kernel/bpf/bpf_lsm.c +++ b/kernel/bpf/bpf_lsm.c @@ -192,6 +192,18 @@ static const struct bpf_func_proto bpf_get_attach_cookie_proto = { .arg1_type = ARG_PTR_TO_CTX, }; +const struct bpf_func_proto *bpf_lsm_sleepable_func_proto(enum bpf_func_id func_id) +{ + switch (func_id) { + case BPF_FUNC_ima_inode_hash: + return &bpf_ima_inode_hash_proto; + case BPF_FUNC_ima_file_hash: + return &bpf_ima_file_hash_proto; + default: + return NULL; + } +} + static const struct bpf_func_proto * bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) { @@ -203,6 +215,10 @@ bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return func_proto; } + func_proto = bpf_lsm_sleepable_func_proto(func_id); + if (func_proto) + return prog->aux->sleepable ? func_proto : NULL; + switch (func_id) { case BPF_FUNC_inode_storage_get: return &bpf_inode_storage_get_proto; @@ -220,10 +236,6 @@ bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_spin_unlock_proto; case BPF_FUNC_bprm_opts_set: return &bpf_bprm_opts_set_proto; - case BPF_FUNC_ima_inode_hash: - return prog->aux->sleepable ? &bpf_ima_inode_hash_proto : NULL; - case BPF_FUNC_ima_file_hash: - return prog->aux->sleepable ? &bpf_ima_file_hash_proto : NULL; case BPF_FUNC_get_attach_cookie: return bpf_prog_has_trampoline(prog) ? &bpf_get_attach_cookie_proto : NULL; #ifdef CONFIG_NET diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 5b9008bc597b..5e4b1566a174 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -1383,9 +1383,27 @@ static int __init bpf_key_sig_kfuncs_init(void) late_initcall(bpf_key_sig_kfuncs_init); #endif /* CONFIG_KEYS */ +const struct bpf_func_proto *bpf_tracing_sleepable_func_proto(enum bpf_func_id func_id) +{ + switch (func_id) { + case BPF_FUNC_copy_from_user: + return &bpf_copy_from_user_proto; + case BPF_FUNC_copy_from_user_task: + return &bpf_copy_from_user_task_proto; + default: + return NULL; + } +} + static const struct bpf_func_proto * bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) { + const struct bpf_func_proto *func_proto; + + func_proto = bpf_tracing_sleepable_func_proto(func_id); + if (func_proto) + return prog->aux->sleepable ? func_proto : NULL; + switch (func_id) { case BPF_FUNC_map_lookup_elem: return &bpf_map_lookup_elem_proto; @@ -1484,10 +1502,6 @@ bpf_tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_jiffies64_proto; case BPF_FUNC_get_task_stack: return &bpf_get_task_stack_proto; - case BPF_FUNC_copy_from_user: - return prog->aux->sleepable ? &bpf_copy_from_user_proto : NULL; - case BPF_FUNC_copy_from_user_task: - return prog->aux->sleepable ? &bpf_copy_from_user_task_proto : NULL; case BPF_FUNC_snprintf_btf: return &bpf_snprintf_btf_proto; case BPF_FUNC_per_cpu_ptr: -- 2.30.2