diff mbox series

[bpf-next,2/4] bpf: allow to access bpf_prog during bpf_struct_access

Message ID 1729737768-124596-3-git-send-email-alibuda@linux.alibaba.com (mailing list archive)
State New
Delegated to: BPF
Headers show
Series net/smc: Introduce smc_bpf_ops | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 206 this patch: 191
netdev/build_tools success Errors and warnings before: 2 (+1) this patch: 2 (+1)
netdev/cc_maintainers warning 26 maintainers not CCed: dietmar.eggemann@arm.com peterz@infradead.org linux-kselftest@vger.kernel.org dsahern@kernel.org yonghong.song@linux.dev tj@kernel.org mcoquelin.stm32@gmail.com alexandre.torgue@foss.st.com linux-arm-kernel@lists.infradead.org mgorman@suse.de vincent.guittot@linaro.org shuah@kernel.org juri.lelli@redhat.com vschneid@redhat.com linux-stm32@st-md-mailman.stormreply.com mykolal@fb.com void@manifault.com oleg@redhat.com coreteam@netfilter.org pablo@netfilter.org netfilter-devel@vger.kernel.org bsegall@google.com kadlec@netfilter.org rostedt@goodmis.org eddyz87@gmail.com mingo@redhat.com
netdev/build_clang fail Errors and warnings before: 257 this patch: 235
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 6964 this patch: 6357
netdev/checkpatch warning WARNING: line length of 88 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 128 this patch: 128
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-next-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-next-VM_Test-4 fail Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-7 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-6 success Logs for aarch64-gcc / test
bpf/vmtest-bpf-next-PR fail PR summary
bpf/vmtest-bpf-next-VM_Test-24 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-next-VM_Test-14 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-15 success Logs for x86_64-gcc / test
bpf/vmtest-bpf-next-VM_Test-8 fail Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for x86_64-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-19 success Logs for x86_64-llvm-17 / test
bpf/vmtest-bpf-next-VM_Test-18 fail Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
bpf/vmtest-bpf-next-VM_Test-23 success Logs for x86_64-llvm-18 / test
bpf/vmtest-bpf-next-VM_Test-13 fail Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-next-VM_Test-10 success Logs for s390x-gcc / test
bpf/vmtest-bpf-next-VM_Test-21 fail Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-12 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-11 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-22 fail Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
bpf/vmtest-bpf-next-VM_Test-17 fail Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17

Commit Message

D. Wythe Oct. 24, 2024, 2:42 a.m. UTC
From: "D. Wythe" <alibuda@linux.alibaba.com>

When implements a struct_ops for a subsystem, the fields allowed to
be written within different callbacks for the same structure might
vary, and applying the same restriction logic could lead to unexpected
issues.

Although we can use kfunc to solve it, creating a new kfunc
just for a simple assignment has low value and introduces obvious
maintenance overhead.

This patch allows the subsystem to implement independent validation
logic for different callbacks by passing an additional prog parameter,
then the subsystem can implement independent logic by checking the
prog->expected_attach_type.

Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
---
 include/linux/bpf.h                                   | 1 +
 include/linux/filter.h                                | 1 +
 kernel/bpf/verifier.c                                 | 2 +-
 kernel/sched/ext.c                                    | 5 +++--
 net/bpf/bpf_dummy_struct_ops.c                        | 1 +
 net/core/filter.c                                     | 7 +++++--
 net/ipv4/bpf_tcp_ca.c                                 | 1 +
 net/netfilter/nf_conntrack_bpf.c                      | 1 +
 tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c | 1 +
 9 files changed, 15 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 19d8ca8..648bafd 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -987,6 +987,7 @@  struct bpf_verifier_ops {
 				  struct bpf_prog *prog, u32 *target_size);
 	int (*btf_struct_access)(struct bpf_verifier_log *log,
 				 const struct bpf_reg_state *reg,
+				 const struct bpf_prog *prog,
 				 int off, int size);
 };
 
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 7d7578a..2b583e2 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -670,6 +670,7 @@  struct sk_filter {
 extern struct mutex nf_conn_btf_access_lock;
 extern int (*nfct_btf_struct_access)(struct bpf_verifier_log *log,
 				     const struct bpf_reg_state *reg,
+					 const struct bpf_prog *prog,
 				     int off, int size);
 
 typedef unsigned int (*bpf_dispatcher_fn)(const void *ctx,
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 9a7ed52..e5f37cb 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -6638,7 +6638,7 @@  static int check_ptr_to_btf_access(struct bpf_verifier_env *env,
 			verbose(env, "verifier internal error: reg->btf must be kernel btf\n");
 			return -EFAULT;
 		}
-		ret = env->ops->btf_struct_access(&env->log, reg, off, size);
+		ret = env->ops->btf_struct_access(&env->log, reg, env->prog, off, size);
 	} else {
 		/* Writes are permitted with default btf_struct_access for
 		 * program allocated objects (which always have ref_obj_id > 0),
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index 410a4df..7b10563 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -5344,8 +5344,9 @@  static bool bpf_scx_is_valid_access(int off, int size,
 }
 
 static int bpf_scx_btf_struct_access(struct bpf_verifier_log *log,
-				     const struct bpf_reg_state *reg, int off,
-				     int size)
+				     const struct bpf_reg_state *reg,
+					 const struct bpf_prog *prog,
+					 int off, int size)
 {
 	const struct btf_type *t;
 
diff --git a/net/bpf/bpf_dummy_struct_ops.c b/net/bpf/bpf_dummy_struct_ops.c
index f71f67c..5bc7aec 100644
--- a/net/bpf/bpf_dummy_struct_ops.c
+++ b/net/bpf/bpf_dummy_struct_ops.c
@@ -234,6 +234,7 @@  static int bpf_dummy_ops_check_member(const struct btf_type *t,
 
 static int bpf_dummy_ops_btf_struct_access(struct bpf_verifier_log *log,
 					   const struct bpf_reg_state *reg,
+					   const struct bpf_prog *prog,
 					   int off, int size)
 {
 	const struct btf_type *state;
diff --git a/net/core/filter.c b/net/core/filter.c
index a88e6924..273393c 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -9014,18 +9014,20 @@  static bool tc_cls_act_is_valid_access(int off, int size,
 
 int (*nfct_btf_struct_access)(struct bpf_verifier_log *log,
 			      const struct bpf_reg_state *reg,
+				  const struct bpf_prog *prog,
 			      int off, int size);
 EXPORT_SYMBOL_GPL(nfct_btf_struct_access);
 
 static int tc_cls_act_btf_struct_access(struct bpf_verifier_log *log,
 					const struct bpf_reg_state *reg,
+					const struct bpf_prog *prog,
 					int off, int size)
 {
 	int ret = -EACCES;
 
 	mutex_lock(&nf_conn_btf_access_lock);
 	if (nfct_btf_struct_access)
-		ret = nfct_btf_struct_access(log, reg, off, size);
+		ret = nfct_btf_struct_access(log, reg, prog, off, size);
 	mutex_unlock(&nf_conn_btf_access_lock);
 
 	return ret;
@@ -9100,13 +9102,14 @@  void bpf_warn_invalid_xdp_action(struct net_device *dev, struct bpf_prog *prog,
 
 static int xdp_btf_struct_access(struct bpf_verifier_log *log,
 				 const struct bpf_reg_state *reg,
+				 const struct bpf_prog *prog,
 				 int off, int size)
 {
 	int ret = -EACCES;
 
 	mutex_lock(&nf_conn_btf_access_lock);
 	if (nfct_btf_struct_access)
-		ret = nfct_btf_struct_access(log, reg, off, size);
+		ret = nfct_btf_struct_access(log, reg, prog, off, size);
 	mutex_unlock(&nf_conn_btf_access_lock);
 
 	return ret;
diff --git a/net/ipv4/bpf_tcp_ca.c b/net/ipv4/bpf_tcp_ca.c
index 5548047..c459774 100644
--- a/net/ipv4/bpf_tcp_ca.c
+++ b/net/ipv4/bpf_tcp_ca.c
@@ -60,6 +60,7 @@  static bool bpf_tcp_ca_is_valid_access(int off, int size,
 
 static int bpf_tcp_ca_btf_struct_access(struct bpf_verifier_log *log,
 					const struct bpf_reg_state *reg,
+					const struct bpf_prog *prog,
 					int off, int size)
 {
 	const struct btf_type *t;
diff --git a/net/netfilter/nf_conntrack_bpf.c b/net/netfilter/nf_conntrack_bpf.c
index 4a136fc..dad3659 100644
--- a/net/netfilter/nf_conntrack_bpf.c
+++ b/net/netfilter/nf_conntrack_bpf.c
@@ -235,6 +235,7 @@  static struct nf_conn *__bpf_nf_ct_lookup(struct net *net,
 /* Check writes into `struct nf_conn` */
 static int _nf_conntrack_btf_struct_access(struct bpf_verifier_log *log,
 					   const struct bpf_reg_state *reg,
+					   const struct bpf_prog *prog,
 					   int off, int size)
 {
 	const struct btf_type *ncit, *nct, *t;
diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
index 8835761..b537480 100644
--- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
@@ -1243,6 +1243,7 @@  static int st_ops_gen_epilogue(struct bpf_insn *insn_buf, const struct bpf_prog
 
 static int st_ops_btf_struct_access(struct bpf_verifier_log *log,
 				    const struct bpf_reg_state *reg,
+					const struct bpf_prog *prog,
 				    int off, int size)
 {
 	if (off < 0 || off + size > sizeof(struct st_ops_args))