From: Eduard Zingerman <eddyz87@gmail.com>
To: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Andrii Nakryiko <andrii@kernel.org>,
Kumar Kartikeya Dwivedi <memxor@gmail.com>,
shung-hsi.yu@suse.com
Cc: John Fastabend <john.fastabend@gmail.com>,
Martin KaFai Lau <martin.lau@linux.dev>,
Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
Jiri Olsa <jolsa@kernel.org>, Shuah Khan <shuah@kernel.org>,
Emil Tsalapatis <emil@etsalapatis.com>,
Ihor Solodrai <ihor.solodrai@linux.dev>,
bpf@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH bpf-next v3 1/3] bpf: Preserve pointer state for commuted arithmetic
Date: Thu, 23 Jul 2026 14:07:20 -0700 [thread overview]
Message-ID: <04c2eab092885ed738fc87f2db344bca1319a90b.camel@gmail.com> (raw)
In-Reply-To: <004a83de52a36e9f3acd6c3fa2d0dfd0a013460d.1784696372.git.chenyy23@mails.tsinghua.edu.cn>
[-- Attachment #1: Type: text/plain, Size: 1358 bytes --]
On Wed, 2026-07-22 at 05:27 +0000, Yiyang Chen wrote:
> When scalar += pointer is handled in adjust_ptr_min_max_vals(), the
> destination register inherits the pointer state from the source pointer.
> Copying only selected fields is fragile because pointer provenance is
> tracked by several bpf_reg_state fields.
>
> Use verifier-env scratch storage to preserve the scalar operand while
> replacing the destination with the full pointer state. This preserves the
> frame number for PTR_TO_STACK registers and keeps parent identity fields
> consistent.
>
> Fixes: f1174f77b50c ("bpf/verifier: rework value tracking")
> Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
> ---
>
> kernel/bpf/verifier.c | 21 ++++++++++++++-------
> 1 file changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 52be0a118cce0..085cbd5222737 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -13726,11 +13726,14 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
Yiyang,
I noticed there there is a temporary 'off' reg allocated on stack by
the caller of this function. So, let's reuse it, and also adjust the
sanitize_err signature to minimize changes.
Could you please re-spin using the attached patches?
Shung-Hsi, wdyt?
...
[-- Attachment #2: 0002-bpf-Preserve-pointer-state-for-commuted-arithmetic.patch --]
[-- Type: text/x-patch, Size: 2649 bytes --]
From e2404beea988a35d8ecb16ed2ac0c36d8729e1b8 Mon Sep 17 00:00:00 2001
From: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
Date: Wed, 22 Jul 2026 05:27:31 +0000
Subject: [PATCH 2/4] bpf: Preserve pointer state for commuted arithmetic
When scalar += pointer is handled in adjust_ptr_min_max_vals(), the
destination register inherits the pointer state from the source pointer.
Copying only selected fields is fragile because pointer provenance is
tracked by several bpf_reg_state fields.
Use verifier-env scratch storage to preserve the scalar operand while
replacing the destination with the full pointer state. This preserves the
frame number for PTR_TO_STACK registers and keeps parent identity fields
consistent.
Fixes: f1174f77b50c ("bpf/verifier: rework value tracking")
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
Tested-by: Daniel Wade <danjwade95@gmail.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
kernel/bpf/verifier.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 712a77693ef5..44a40c766f82 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -13794,11 +13794,12 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
return -EACCES;
}
- /* In case of 'scalar += pointer', dst_reg inherits pointer type and id.
- * The id may be overwritten later if we create a new variable offset.
+ /* For 'scalar += pointer', dst_reg inherits the complete pointer
+ * register state. Individual fields may be adjusted later by pointer
+ * arithmetic. Callers guarantee that below does not overwrite off_reg.
*/
- dst_reg->type = ptr_reg->type;
- dst_reg->id = ptr_reg->id;
+ if (dst_reg != ptr_reg)
+ *dst_reg = *ptr_reg;
if (!check_reg_sane_offset_scalar(env, off_reg, ptr_reg->type) ||
!check_reg_sane_offset_ptr(env, ptr_reg, ptr_reg->type))
@@ -13841,7 +13842,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
}
break;
case BPF_SUB:
- if (dst_reg == off_reg) {
+ if (dst_reg != ptr_reg) {
/* scalar -= pointer. Creates an unknown scalar */
verbose(env, "R%d tried to subtract pointer from scalar\n",
dst);
@@ -14859,8 +14860,8 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
err = mark_chain_precision(env, insn->dst_reg);
if (err)
return err;
- return adjust_ptr_min_max_vals(env, insn,
- src_reg, dst_reg);
+ off_reg = *dst_reg;
+ return adjust_ptr_min_max_vals(env, insn, src_reg, &off_reg);
}
} else if (ptr_reg) {
/* pointer += scalar */
--
2.53.0-Meta
[-- Attachment #3: 0001-bpf-simplify-sanitize_err-signature.patch --]
[-- Type: text/x-patch, Size: 2990 bytes --]
From df9145952923ef35e78527701200d53b76ec87cd Mon Sep 17 00:00:00 2001
From: Eduard Zingerman <eddyz87@gmail.com>
Date: Thu, 23 Jul 2026 11:04:55 -0700
Subject: [PATCH 1/4] bpf: simplify sanitize_err() signature
The sanitize_err() function is called when:
- ptr += scalar
- scalar += ptr
- scalar += scalar
ALU operations are processed.
This commit drops offset and pointer registers parameters from its
signature to simplify the follow-up changes for 'scalar += ptr' case.
regs[src].type is safe to access, as it is not mutated by the callers.
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
kernel/bpf/verifier.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 52be0a118cce..712a77693ef5 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -13608,23 +13608,21 @@ static void sanitize_mark_insn_seen(struct bpf_verifier_env *env)
env->insn_aux_data[env->insn_idx].seen = env->pass_cnt;
}
-static int sanitize_err(struct bpf_verifier_env *env,
- const struct bpf_insn *insn, int reason,
- const struct bpf_reg_state *off_reg,
- const struct bpf_reg_state *dst_reg)
+static int sanitize_err(struct bpf_verifier_env *env, const struct bpf_insn *insn, int reason)
{
static const char *err = "pointer arithmetic with it prohibited for !root";
const char *op = BPF_OP(insn->code) == BPF_ADD ? "add" : "sub";
u32 dst = insn->dst_reg, src = insn->src_reg;
+ struct bpf_reg_state *regs = cur_regs(env);
switch (reason) {
case REASON_BOUNDS:
verbose(env, "R%d has unknown scalar with mixed signed bounds, %s\n",
- off_reg == dst_reg ? dst : src, err);
+ regs[src].type == SCALAR_VALUE ? src : dst, err);
break;
case REASON_TYPE:
verbose(env, "R%d has pointer with unsupported alu operation, %s\n",
- off_reg == dst_reg ? src : dst, err);
+ regs[src].type == SCALAR_VALUE ? dst : src, err);
break;
case REASON_PATHS:
verbose(env, "R%d tried to %s from different maps, paths or scalars, %s\n",
@@ -13813,7 +13811,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
ret = sanitize_ptr_alu(env, insn, ptr_reg, off_reg, dst_reg,
&info, false);
if (ret < 0)
- return sanitize_err(env, insn, ret, off_reg, dst_reg);
+ return sanitize_err(env, insn, ret);
}
switch (opcode) {
@@ -13906,7 +13904,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
return -EFAULT;
}
if (ret < 0)
- return sanitize_err(env, insn, ret, off_reg, dst_reg);
+ return sanitize_err(env, insn, ret);
}
return 0;
@@ -14658,7 +14656,7 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
if (sanitize_needed(opcode)) {
ret = sanitize_val_alu(env, insn);
if (ret < 0)
- return sanitize_err(env, insn, ret, NULL, NULL);
+ return sanitize_err(env, insn, ret);
}
/* Calculate sign/unsigned bounds and tnum for alu32 and alu64 bit ops.
--
2.53.0-Meta
next prev parent reply other threads:[~2026-07-23 21:07 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-22 5:27 [PATCH bpf-next v3 0/3] bpf: Preserve pointer state for commuted arithmetic Yiyang Chen
2026-07-22 5:27 ` [PATCH bpf-next v3 1/3] " Yiyang Chen
2026-07-23 3:45 ` Shung-Hsi Yu
2026-07-23 4:25 ` Shung-Hsi Yu
2026-07-23 17:35 ` Eduard Zingerman
2026-07-23 17:57 ` Eduard Zingerman
2026-07-23 21:07 ` Eduard Zingerman [this message]
2026-07-24 3:05 ` Shung-Hsi Yu
2026-07-24 5:07 ` Eduard Zingerman
2026-07-22 5:27 ` [PATCH bpf-next v3 2/3] bpf: Propagate untrusted pointer state in " Yiyang Chen
2026-07-22 5:27 ` [PATCH bpf-next v3 3/3] selftests/bpf: Cover commuted pointer state propagation Yiyang Chen
2026-07-23 21:18 ` Eduard Zingerman
2026-07-22 11:38 ` [PATCH bpf-next v3 0/3] bpf: Preserve pointer state for commuted arithmetic Daniel Wade
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=04c2eab092885ed738fc87f2db344bca1319a90b.camel@gmail.com \
--to=eddyz87@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=chenyy23@mails.tsinghua.edu.cn \
--cc=daniel@iogearbox.net \
--cc=emil@etsalapatis.com \
--cc=ihor.solodrai@linux.dev \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=shuah@kernel.org \
--cc=shung-hsi.yu@suse.com \
--cc=song@kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox