All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eduard Zingerman <eddyz87@gmail.com>
To: bpf@vger.kernel.org, ast@kernel.org
Cc: andrii@kernel.org, daniel@iogearbox.net, martin.lau@linux.dev,
	kernel-team@fb.com, yonghong.song@linux.dev, memxor@gmail.com,
	Eduard Zingerman <eddyz87@gmail.com>
Subject: [RFC bpf-next 06/11] bpf: KERNEL_VALUE register type
Date: Thu,  7 Nov 2024 09:50:35 -0800	[thread overview]
Message-ID: <20241107175040.1659341-7-eddyz87@gmail.com> (raw)
In-Reply-To: <20241107175040.1659341-1-eddyz87@gmail.com>

Follow-up patch adds inlinable kfuncs as subprograms of a bpf program
being verified. Bodies of these helpers are considered trusted and
don't require verification. To facilitate this, add a new register
type: KERNEL_VALUE.
- ALU operations on KERNEL_VALUEs return KERNEL_VALUE;
- stores with KERNEL_VALUE destination registers are legal;
- loads with KERNEL_VALUE source registers are legal and
  set destination registers to KERNEL_VALUE;
- KERNEL_VALUEs do not have any additional associated information:
  no ids, no range, etc.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
 include/linux/bpf.h   |  1 +
 kernel/bpf/log.c      |  1 +
 kernel/bpf/verifier.c | 24 +++++++++++++++++++++++-
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 2bcc9161687b..75f57f791cd3 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -941,6 +941,7 @@ enum bpf_reg_type {
 	PTR_TO_BUF,		 /* reg points to a read/write buffer */
 	PTR_TO_FUNC,		 /* reg points to a bpf program function */
 	CONST_PTR_TO_DYNPTR,	 /* reg points to a const struct bpf_dynptr */
+	KERNEL_VALUE,		 /* pointer or scalar, any operation produces another KERNEL_VALUE */
 	__BPF_REG_TYPE_MAX,
 
 	/* Extended reg_types. */
diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c
index 4a858fdb6476..87ab01b8fc1a 100644
--- a/kernel/bpf/log.c
+++ b/kernel/bpf/log.c
@@ -463,6 +463,7 @@ const char *reg_type_str(struct bpf_verifier_env *env, enum bpf_reg_type type)
 		[PTR_TO_FUNC]		= "func",
 		[PTR_TO_MAP_KEY]	= "map_key",
 		[CONST_PTR_TO_DYNPTR]	= "dynptr_ptr",
+		[KERNEL_VALUE]		= "kval",
 	};
 
 	if (type & PTR_MAYBE_NULL) {
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index d4ea7fd8a967..f38f73cc740b 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2388,6 +2388,12 @@ static void mark_reg_unknown(struct bpf_verifier_env *env,
 	__mark_reg_unknown(env, regs + regno);
 }
 
+static void mark_reg_kernel_value(struct bpf_reg_state *reg)
+{
+	__mark_reg_unknown_imprecise(reg);
+	reg->type = KERNEL_VALUE;
+}
+
 static int __mark_reg_s32_range(struct bpf_verifier_env *env,
 				struct bpf_reg_state *regs,
 				u32 regno,
@@ -4534,6 +4540,9 @@ static bool __is_pointer_value(bool allow_ptr_leaks,
 	if (allow_ptr_leaks)
 		return false;
 
+	if (reg->type == KERNEL_VALUE)
+		return false;
+
 	return reg->type != SCALAR_VALUE;
 }
 
@@ -7208,6 +7217,9 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
 	} else if (reg->type == PTR_TO_ARENA) {
 		if (t == BPF_READ && value_regno >= 0)
 			mark_reg_unknown(env, regs, value_regno);
+	} else if (reg->type == KERNEL_VALUE) {
+		if (t == BPF_READ && value_regno >= 0)
+			mark_reg_kernel_value(regs + value_regno);
 	} else {
 		verbose(env, "R%d invalid mem access '%s'\n", regno,
 			reg_type_str(env, reg->type));
@@ -14319,6 +14331,13 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
 
 	if (BPF_SRC(insn->code) == BPF_X) {
 		src_reg = &regs[insn->src_reg];
+
+		if (src_reg->type == KERNEL_VALUE || dst_reg->type == KERNEL_VALUE) {
+			mark_reg_kernel_value(src_reg);
+			mark_reg_kernel_value(dst_reg);
+			return 0;
+		}
+
 		if (src_reg->type != SCALAR_VALUE) {
 			if (dst_reg->type != SCALAR_VALUE) {
 				/* Combining two pointers by any ALU op yields
@@ -14358,6 +14377,9 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
 				return err;
 		}
 	} else {
+		if (dst_reg->type == KERNEL_VALUE)
+			return 0;
+
 		/* Pretend the src is a reg with a known value, since we only
 		 * need to be able to read from this state.
 		 */
@@ -15976,7 +15998,7 @@ static int check_return_code(struct bpf_verifier_env *env, int regno, const char
 	}
 
 	if (is_subprog && !frame->in_exception_callback_fn) {
-		if (reg->type != SCALAR_VALUE) {
+		if (reg->type != SCALAR_VALUE && reg->type != KERNEL_VALUE) {
 			verbose(env, "At subprogram exit the register R%d is not a scalar value (%s)\n",
 				regno, reg_type_str(env, reg->type));
 			return -EINVAL;
-- 
2.47.0


  parent reply	other threads:[~2024-11-07 17:51 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-07 17:50 [RFC bpf-next 00/11] bpf: inlinable kfuncs for BPF Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 01/11] bpf: use branch predictions in opt_hard_wire_dead_code_branches() Eduard Zingerman
2024-11-14 22:20   ` Eduard Zingerman
2024-11-15  0:17     ` Andrii Nakryiko
2024-11-15  0:19       ` Andrii Nakryiko
2024-11-15  0:50         ` Eduard Zingerman
2024-11-15  3:03           ` Andrii Nakryiko
2024-11-15  0:20       ` Eduard Zingerman
2024-11-15  0:27         ` Alexei Starovoitov
2024-11-15  0:33           ` Eduard Zingerman
2024-11-15  0:38             ` Alexei Starovoitov
2024-11-15  0:43               ` Eduard Zingerman
2024-11-15  0:16   ` Andrii Nakryiko
2024-11-07 17:50 ` [RFC bpf-next 02/11] selftests/bpf: tests for opt_hard_wire_dead_code_branches() Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 03/11] bpf: shared BPF/native kfuncs Eduard Zingerman
2024-11-08  1:43   ` kernel test robot
2024-11-08 20:43   ` Toke Høiland-Jørgensen
2024-11-08 21:25     ` Eduard Zingerman
2024-11-11 18:41       ` Toke Høiland-Jørgensen
2024-11-15  0:27   ` Andrii Nakryiko
2024-11-07 17:50 ` [RFC bpf-next 04/11] bpf: allow specifying inlinable kfuncs in modules Eduard Zingerman
2024-11-09  6:57   ` kernel test robot
2024-11-09  7:07   ` kernel test robot
2024-11-07 17:50 ` [RFC bpf-next 05/11] bpf: dynamic allocation for bpf_verifier_env->subprog_info Eduard Zingerman
2024-11-07 17:50 ` Eduard Zingerman [this message]
2024-11-07 17:50 ` [RFC bpf-next 07/11] bpf: instantiate inlinable kfuncs before verification Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 08/11] bpf: special rules for kernel function calls inside inlinable kfuncs Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 09/11] bpf: move selected dynptr kfuncs to inlinable_kfuncs.c Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 10/11] selftests/bpf: tests to verify handling of inlined kfuncs Eduard Zingerman
2024-11-07 22:04   ` Jeff Johnson
2024-11-07 22:08     ` Eduard Zingerman
2024-11-07 22:19       ` Jeff Johnson
2024-11-07 23:00         ` Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 11/11] selftests/bpf: dynptr_slice benchmark Eduard Zingerman
2024-11-08 20:41 ` [RFC bpf-next 00/11] bpf: inlinable kfuncs for BPF Toke Høiland-Jørgensen
2024-11-08 23:01   ` Eduard Zingerman
2024-11-11 18:42     ` Toke Høiland-Jørgensen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241107175040.1659341-7-eddyz87@gmail.com \
    --to=eddyz87@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=kernel-team@fb.com \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=yonghong.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.