[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20260107-skb-meta-safeproof-netdevs-rx-only-v3-13-0d461c5e4764@cloudflare.com>
Date: Wed, 07 Jan 2026 15:28:13 +0100
From: Jakub Sitnicki <jakub@...udflare.com>
To: bpf@...r.kernel.org
Cc: netdev@...r.kernel.org, "David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>, Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>, Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Jesper Dangaard Brouer <hawk@...nel.org>,
John Fastabend <john.fastabend@...il.com>,
Stanislav Fomichev <sdf@...ichev.me>, Simon Horman <horms@...nel.org>,
Andrii Nakryiko <andrii@...nel.org>,
Martin KaFai Lau <martin.lau@...ux.dev>,
Eduard Zingerman <eddyz87@...il.com>, Song Liu <song@...nel.org>,
Yonghong Song <yonghong.song@...ux.dev>, KP Singh <kpsingh@...nel.org>,
Hao Luo <haoluo@...gle.com>, Jiri Olsa <jolsa@...nel.org>,
kernel-team@...udflare.com
Subject: [PATCH bpf-next v3 13/17] bpf, verifier: Propagate packet access
flags to gen_prologue
Change gen_prologue() to accept the packet access flags bitmap. This allows
gen_prologue() to inspect multiple access patterns when needed.
No functional change.
Reviewed-by: Eduard Zingerman <eddyz87@...il.com>
Signed-off-by: Jakub Sitnicki <jakub@...udflare.com>
---
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 5936f8e2996f..1dba2caee09c 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1106,7 +1106,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 95818a7eedff..daa90c81d802 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -21768,7 +21768,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) {
@@ -21796,13 +21795,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 d43df98e1ded..07af2a94cc9a 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -9052,7 +9052,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
@@ -9061,12 +9061,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)
@@ -9135,10 +9135,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,
@@ -9476,10 +9477,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 b9771788b9b3..dc7b9db7e785 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 1c41d03bd5a1..d698e45783e3 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
@@ -1397,7 +1397,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;
@@ -1473,7 +1473,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;
@@ -1483,7 +1483,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
Powered by blists - more mailing lists