All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: Eduard Zingerman <eddyz87@gmail.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Emil Tsalapatis <emil@etsalapatis.com>, Tejun Heo <tj@kernel.org>,
	Amery Hung <ameryhung@gmail.com>,
	kkd@meta.com, kernel-team@meta.com
Subject: [PATCH bpf-next v5 02/11] bpf: Record raw memory arguments during argument checking
Date: Mon, 21 Sep 2026 04:38:26 +0200	[thread overview]
Message-ID: <20260921023843.411943-3-memxor@gmail.com> (raw)
In-Reply-To: <20260921023843.411943-1-memxor@gmail.com>

From: Eduard Zingerman <eddyz87@gmail.com>

Record raw outputs in check_func_arg() after resolving their memory type,
instead of pre-recording them in check_raw_mode_ok(). Keep prototype
validation separate from per-call output tracking so kfuncs can share the
latter in a following patch.

For bpf_strtol(), bpf_strtoul() and bpf_kallsyms_lookup_name(), a variable-size
input is checked before the arg4 output. Recording outputs as their arguments
are checked prevents that input from clearing the output's raw mode early.
Only clear raw mode when a variable size belongs to the recorded output:
an unrelated later input must also preserve an earlier output descriptor.

For bpf_map_peek_elem() on a bloom filter, type resolution removes MEM_UNINIT
and MEM_WRITE because the value is an input. Recording the resolved type makes
the later bloom-filter-specific raw-mode reset unnecessary. Reuse the same
raw-memory predicate for output recording and prototype validation.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
 kernel/bpf/verifier.c | 31 ++++++++++++++-----------------
 1 file changed, 14 insertions(+), 17 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 18aad4886f9c..67c1abfde922 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -7217,12 +7217,13 @@ static int check_mem_size_reg(struct bpf_verifier_env *env,
 	 */
 	meta->msize_max_value = reg_umax(size_reg);
 
-	/* The register is SCALAR_VALUE; the access check happens using
-	 * its boundaries. For unprivileged variable accesses, disable
-	 * raw mode so that the program is required to initialize all
-	 * the memory that the helper could just partially fill up.
+	/*
+	 * A variable size does not guarantee that the call initializes the whole
+	 * checked range. Disable raw mode for this output and apply the ordinary
+	 * stack initialization checks, including their privilege exceptions.
 	 */
-	if (!tnum_is_const(size_reg->var_off))
+	if (!tnum_is_const(size_reg->var_off) &&
+	    meta->arg_raw_mem.regno == reg_from_argno(mem_argno))
 		meta->arg_raw_mem.regno = 0;
 
 	if (reg_smin(size_reg) < 0) {
@@ -8940,6 +8941,9 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, u32 slot, u32 p
 	if (err)
 		return err;
 
+	if (!meta->btf && arg_type_is_raw_mem(arg_type))
+		meta->arg_raw_mem.regno = slot + 1;
+
 	if (bpf_register_is_null(reg) && type_may_be_null(arg_type)) {
 		err = mark_arg_precision(env, argno);
 		if (err)
@@ -9029,14 +9033,6 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, u32 slot, u32 p
 			return -EFAULT;
 		}
 
-		/*
-		 * Disable raw mode for bpf_map_peek_elem() on a bloom filter. The helper reads
-		 * the value buffer as an input rather than filling it.
-		 */
-		if (is_helper_call(meta, BPF_FUNC_map_peek_elem) &&
-		    meta->map.ptr->map_type == BPF_MAP_TYPE_BLOOM_FILTER)
-			meta->arg_raw_mem.regno = 0;
-
 		err = check_helper_mem_access(env, reg, argno, meta->map.ptr->value_size,
 					      arg_type & MEM_WRITE ? BPF_WRITE : BPF_READ,
 					      false, meta, NULL);
@@ -9860,8 +9856,9 @@ static int check_map_func_compatibility(struct bpf_verifier_env *env,
 	return -EINVAL;
 }
 
-static bool check_raw_mode_ok(const struct bpf_func_proto *fn, struct bpf_call_arg_meta *meta)
+static bool check_raw_mode_ok(const struct bpf_func_proto *fn)
 {
+	bool seen = false;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(fn->arg_type); i++) {
@@ -9869,9 +9866,9 @@ static bool check_raw_mode_ok(const struct bpf_func_proto *fn, struct bpf_call_a
 			break;
 		if (!arg_type_is_raw_mem(fn->arg_type[i]))
 			continue;
-		if (meta->arg_raw_mem.regno)
+		if (seen)
 			return false;
-		meta->arg_raw_mem.regno = i + 1;
+		seen = true;
 	}
 
 	return true;
@@ -10003,7 +10000,7 @@ static int check_func_proto(struct bpf_verifier_env *env, const struct bpf_func_
 			    struct bpf_call_arg_meta *meta)
 {
 	return check_arg_prog_aux(env, fn) &&
-	       check_raw_mode_ok(fn, meta) &&
+	       check_raw_mode_ok(fn) &&
 	       check_arg_pair_ok(fn) &&
 	       check_mem_arg_rw_flag_ok(fn) &&
 	       check_proto_release_reg(fn, meta) &&
-- 
2.53.0


  parent reply	other threads:[~2026-09-21  2:38 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-21  2:38 [PATCH bpf-next v5 00/11] Fix generic __uninit kfunc output buffers Kumar Kartikeya Dwivedi
2026-09-21  2:38 ` [PATCH bpf-next v5 01/11] selftests/bpf: Allow privileged preparation for capability tests Kumar Kartikeya Dwivedi
2026-09-21  2:38 ` Kumar Kartikeya Dwivedi [this message]
2026-09-21  2:38 ` [PATCH bpf-next v5 03/11] bpf: Check __uninit kfunc output buffers as write-only Kumar Kartikeya Dwivedi
2026-09-21  3:54   ` bot+bpf-ci
2026-09-21  2:38 ` [PATCH bpf-next v5 04/11] bpf: Fix generic __uninit kfunc output buffers Kumar Kartikeya Dwivedi
2026-09-21  2:38 ` [PATCH bpf-next v5 05/11] selftests/bpf: Cover generic __uninit output initialization Kumar Kartikeya Dwivedi
2026-09-21  2:38 ` [PATCH bpf-next v5 06/11] bpf: Support multiple __uninit kfunc output arguments Kumar Kartikeya Dwivedi
2026-09-21  2:38 ` [PATCH bpf-next v5 07/11] selftests/bpf: Cover __uninit kfunc output argument slots Kumar Kartikeya Dwivedi
2026-09-21  2:38 ` [PATCH bpf-next v5 08/11] bpf: Preserve stack initialization for generic output buffers Kumar Kartikeya Dwivedi
2026-09-21  3:54   ` bot+bpf-ci
2026-09-21  2:38 ` [PATCH bpf-next v5 09/11] selftests/bpf: Cover generic output stack initialization Kumar Kartikeya Dwivedi
2026-09-21  3:54   ` bot+bpf-ci
2026-09-21  2:38 ` [PATCH bpf-next v5 10/11] bpf: Check read access for helper input/output buffers Kumar Kartikeya Dwivedi
2026-09-21  2:38 ` [PATCH bpf-next v5 11/11] selftests/bpf: Cover helper memory access permissions Kumar Kartikeya Dwivedi
2026-09-21  3:54   ` bot+bpf-ci
2026-09-21 17:20 ` [PATCH bpf-next v5 00/11] Fix generic __uninit kfunc output buffers patchwork-bot+netdevbpf

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=20260921023843.411943-3-memxor@gmail.com \
    --to=memxor@gmail.com \
    --cc=ameryhung@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=emil@etsalapatis.com \
    --cc=kernel-team@meta.com \
    --cc=kkd@meta.com \
    --cc=tj@kernel.org \
    /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.