Change gen_prologue() to accept the packet access flags bitmap. This allows gen_prologue() to inspect multiple access patterns when needed. No functional change. Signed-off-by: Jakub Sitnicki --- include/linux/bpf.h | 2 +- kernel/bpf/cgroup.c | 2 +- kernel/bpf/verifier.c | 6 ++---- net/core/filter.c | 15 ++++++++------- net/sched/bpf_qdisc.c | 3 ++- tools/testing/selftests/bpf/test_kmods/bpf_testmod.c | 6 +++--- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index d808253f2e94..d16987e94d98 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1076,7 +1076,7 @@ struct bpf_verifier_ops { bool (*is_valid_access)(int off, int size, enum bpf_access_type type, const struct bpf_prog *prog, struct bpf_insn_access_aux *info); - int (*gen_prologue)(struct bpf_insn *insn, bool direct_write, + int (*gen_prologue)(struct bpf_insn *insn, u32 pkt_access_flags, const struct bpf_prog *prog); int (*gen_epilogue)(struct bpf_insn *insn, const struct bpf_prog *prog, s16 ctx_stack_off); diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 69988af44b37..d96465cd7d43 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -2694,7 +2694,7 @@ static u32 cg_sockopt_convert_ctx_access(enum bpf_access_type type, } static int cg_sockopt_get_prologue(struct bpf_insn *insn_buf, - bool direct_write, + u32 pkt_access_flags, const struct bpf_prog *prog) { /* Nothing to do for sockopt argument. The data is kzalloc'ated. diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 4c84b0cd399e..bb4e70913ab4 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -21200,7 +21200,6 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) struct bpf_prog *new_prog; enum bpf_access_type type; bool is_narrower_load; - bool seen_direct_write; int epilogue_idx = 0; if (ops->gen_epilogue) { @@ -21228,13 +21227,12 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) } } - seen_direct_write = env->seen_packet_access & PA_F_DIRECT_WRITE; - if (ops->gen_prologue || seen_direct_write) { + if (ops->gen_prologue || (env->seen_packet_access & PA_F_DIRECT_WRITE)) { if (!ops->gen_prologue) { verifier_bug(env, "gen_prologue is null"); return -EFAULT; } - cnt = ops->gen_prologue(insn_buf, seen_direct_write, env->prog); + cnt = ops->gen_prologue(insn_buf, env->seen_packet_access, env->prog); if (cnt >= INSN_BUF_SIZE) { verifier_bug(env, "prologue is too long"); return -EFAULT; diff --git a/net/core/filter.c b/net/core/filter.c index 4124becf8604..334421910107 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -9042,7 +9042,7 @@ static bool sock_filter_is_valid_access(int off, int size, prog->expected_attach_type); } -static int bpf_noop_prologue(struct bpf_insn *insn_buf, bool direct_write, +static int bpf_noop_prologue(struct bpf_insn *insn_buf, u32 pkt_access_flags, const struct bpf_prog *prog) { /* Neither direct read nor direct write requires any preliminary @@ -9051,12 +9051,12 @@ static int bpf_noop_prologue(struct bpf_insn *insn_buf, bool direct_write, return 0; } -static int bpf_unclone_prologue(struct bpf_insn *insn_buf, bool direct_write, +static int bpf_unclone_prologue(struct bpf_insn *insn_buf, u32 pkt_access_flags, const struct bpf_prog *prog, int drop_verdict) { struct bpf_insn *insn = insn_buf; - if (!direct_write) + if (!(pkt_access_flags & PA_F_DIRECT_WRITE)) return 0; /* if (!skb->cloned) @@ -9125,10 +9125,11 @@ static int bpf_gen_ld_abs(const struct bpf_insn *orig, return insn - insn_buf; } -static int tc_cls_act_prologue(struct bpf_insn *insn_buf, bool direct_write, +static int tc_cls_act_prologue(struct bpf_insn *insn_buf, u32 pkt_access_flags, const struct bpf_prog *prog) { - return bpf_unclone_prologue(insn_buf, direct_write, prog, TC_ACT_SHOT); + return bpf_unclone_prologue(insn_buf, pkt_access_flags, prog, + TC_ACT_SHOT); } static bool tc_cls_act_is_valid_access(int off, int size, @@ -9466,10 +9467,10 @@ static bool sock_ops_is_valid_access(int off, int size, return true; } -static int sk_skb_prologue(struct bpf_insn *insn_buf, bool direct_write, +static int sk_skb_prologue(struct bpf_insn *insn_buf, u32 pkt_access_flags, const struct bpf_prog *prog) { - return bpf_unclone_prologue(insn_buf, direct_write, prog, SK_DROP); + return bpf_unclone_prologue(insn_buf, pkt_access_flags, prog, SK_DROP); } static bool sk_skb_is_valid_access(int off, int size, diff --git a/net/sched/bpf_qdisc.c b/net/sched/bpf_qdisc.c index adcb618a2bfc..ae44d0dab073 100644 --- a/net/sched/bpf_qdisc.c +++ b/net/sched/bpf_qdisc.c @@ -132,7 +132,8 @@ static int bpf_qdisc_btf_struct_access(struct bpf_verifier_log *log, BTF_ID_LIST_SINGLE(bpf_qdisc_init_prologue_ids, func, bpf_qdisc_init_prologue) -static int bpf_qdisc_gen_prologue(struct bpf_insn *insn_buf, bool direct_write, +static int bpf_qdisc_gen_prologue(struct bpf_insn *insn_buf, + u32 direct_access_flags, const struct bpf_prog *prog) { struct bpf_insn *insn = insn_buf; diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c index 8eeebaa951f0..286cbb8c5623 100644 --- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c +++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c @@ -1369,7 +1369,7 @@ static int bpf_test_mod_st_ops__test_pro_epilogue(struct st_ops_args *args) static int bpf_cgroup_from_id_id; static int bpf_cgroup_release_id; -static int st_ops_gen_prologue_with_kfunc(struct bpf_insn *insn_buf, bool direct_write, +static int st_ops_gen_prologue_with_kfunc(struct bpf_insn *insn_buf, const struct bpf_prog *prog) { struct bpf_insn *insn = insn_buf; @@ -1445,7 +1445,7 @@ static int st_ops_gen_epilogue_with_kfunc(struct bpf_insn *insn_buf, const struc } #define KFUNC_PRO_EPI_PREFIX "test_kfunc_" -static int st_ops_gen_prologue(struct bpf_insn *insn_buf, bool direct_write, +static int st_ops_gen_prologue(struct bpf_insn *insn_buf, u32 pkt_access_flags, const struct bpf_prog *prog) { struct bpf_insn *insn = insn_buf; @@ -1455,7 +1455,7 @@ static int st_ops_gen_prologue(struct bpf_insn *insn_buf, bool direct_write, return 0; if (!strncmp(prog->aux->name, KFUNC_PRO_EPI_PREFIX, strlen(KFUNC_PRO_EPI_PREFIX))) - return st_ops_gen_prologue_with_kfunc(insn_buf, direct_write, prog); + return st_ops_gen_prologue_with_kfunc(insn_buf, prog); /* r6 = r1[0]; // r6 will be "struct st_ops *args". r1 is "u64 *ctx". * r7 = r6->a; -- 2.43.0