Skip to content

Commit 85dd93a

Browse files
author
Alexei Starovoitov
committed
Merge branch 'enhance-bpf-global-subprogs-with-argument-tags'
Andrii Nakryiko says: ==================== Enhance BPF global subprogs with argument tags This patch set adds verifier support for annotating user's global BPF subprog arguments with few commonly requested annotations, to improve global subprog verification experience. These tags are: - ability to annotate a special PTR_TO_CTX argument; - ability to annotate a generic PTR_TO_MEM as non-null. We utilize btf_decl_tag attribute for this and provide two helper macros as part of bpf_helpers.h in libbpf (patch #8). Besides this we also add abilit to pass a pointer to dynptr into global subprog. This is done based on type name match (struct bpf_dynptr *). This allows to pass dynptrs into global subprogs, for use cases that deal with variable-sized generic memory pointers. Big chunk of the patch set (patches #1 through #5) are various refactorings to make verifier internals around global subprog validation logic easier to extend and support long term, eliminating BTF parsing logic duplication, factoring out argument expectation definitions from BTF parsing, etc. New functionality is added in patch #6 (ctx and non-null) and patch #7 (dynptr), extending global subprog checks with awareness for arg tags. Patch #9 adds simple tests validating each of the added tags and dynptr argument passing. Patch #10 adds a simple negative case for freplace programs to make sure that target BPF programs with "unreliable" BTF func proto cannot be freplaced. v2->v3: - patch #10 improved by checking expected verifier error (Eduard); v1->v2: - dropped packet args for now (Eduard); - added back unreliable=true detection for entry BPF programs (Eduard); - improved subprog arg validation (Eduard); - switched dynptr arg from tag to just type name based check (Eduard). ==================== Link: https://lore.kernel.org/r/20231215011334.2307144-1-andrii@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2 parents c337f23 + f0a5056 commit 85dd93a

File tree

14 files changed

+416
-270
lines changed

14 files changed

+416
-270
lines changed

include/linux/bpf.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2466,12 +2466,7 @@ int btf_distill_func_proto(struct bpf_verifier_log *log,
24662466
struct btf_func_model *m);
24672467

24682468
struct bpf_reg_state;
2469-
int btf_check_subprog_arg_match(struct bpf_verifier_env *env, int subprog,
2470-
struct bpf_reg_state *regs);
2471-
int btf_check_subprog_call(struct bpf_verifier_env *env, int subprog,
2472-
struct bpf_reg_state *regs);
2473-
int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog,
2474-
struct bpf_reg_state *reg, u32 *nargs);
2469+
int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog);
24752470
int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *prog,
24762471
struct btf *btf, const struct btf_type *t);
24772472
const char *btf_find_decl_tag_value(const struct btf *btf, const struct btf_type *pt,

include/linux/bpf_verifier.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,13 @@ static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log)
606606

607607
#define BPF_MAX_SUBPROGS 256
608608

609+
struct bpf_subprog_arg_info {
610+
enum bpf_arg_type arg_type;
611+
union {
612+
u32 mem_size;
613+
};
614+
};
615+
609616
struct bpf_subprog_info {
610617
/* 'start' has to be the first field otherwise find_subprog() won't work */
611618
u32 start; /* insn idx of function entry point */
@@ -617,6 +624,10 @@ struct bpf_subprog_info {
617624
bool is_cb: 1;
618625
bool is_async_cb: 1;
619626
bool is_exception_cb: 1;
627+
bool args_cached: 1;
628+
629+
u8 arg_cnt;
630+
struct bpf_subprog_arg_info args[MAX_BPF_FUNC_REG_ARGS];
620631
};
621632

622633
struct bpf_verifier_env;
@@ -727,6 +738,16 @@ struct bpf_verifier_env {
727738
char tmp_str_buf[TMP_STR_BUF_LEN];
728739
};
729740

741+
static inline struct bpf_func_info_aux *subprog_aux(struct bpf_verifier_env *env, int subprog)
742+
{
743+
return &env->prog->aux->func_info_aux[subprog];
744+
}
745+
746+
static inline struct bpf_subprog_info *subprog_info(struct bpf_verifier_env *env, int subprog)
747+
{
748+
return &env->subprog_info[subprog];
749+
}
750+
730751
__printf(2, 0) void bpf_verifier_vlog(struct bpf_verifier_log *log,
731752
const char *fmt, va_list args);
732753
__printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_env *env,
@@ -764,14 +785,6 @@ bpf_prog_offload_replace_insn(struct bpf_verifier_env *env, u32 off,
764785
void
765786
bpf_prog_offload_remove_insns(struct bpf_verifier_env *env, u32 off, u32 cnt);
766787

767-
int check_ptr_off_reg(struct bpf_verifier_env *env,
768-
const struct bpf_reg_state *reg, int regno);
769-
int check_func_arg_reg_off(struct bpf_verifier_env *env,
770-
const struct bpf_reg_state *reg, int regno,
771-
enum bpf_arg_type arg_type);
772-
int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg,
773-
u32 regno, u32 mem_size);
774-
775788
/* this lives here instead of in bpf.h because it needs to dereference tgt_prog */
776789
static inline u64 bpf_trampoline_compute_key(const struct bpf_prog *tgt_prog,
777790
struct btf *btf, u32 btf_id)

0 commit comments

Comments
 (0)