From: sashiko-bot@kernel.org
To: "Eduard Zingerman" <eddyz87@gmail.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next 3/5] bpf: infer zext_dst based on static register liveness analysis
Date: Fri, 31 Jul 2026 19:26:34 +0000 [thread overview]
Message-ID: <20260731192635.8B8111F00AC4@smtp.kernel.org> (raw)
In-Reply-To: <20260731-static-zext-v1-3-98a4dc73e94b@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] Incorrect static liveness tracking for 64-bit conditional jumps leads to missing zero-extensions (`zext_dst`), resulting in verifier/runtime state divergence and potential privilege escalation.
--
--- Patch [3]: [PATCH bpf-next 3/5] bpf: infer zext_dst based on static register liveness analysis ---
commit ab8592d6a434dbfed0cbb0bd067d9032b308db8d
Author: Eduard Zingerman <eddyz87@gmail.com>
bpf: infer zext_dst based on static register liveness analysis
This commit replaces the dynamic subreg_def based zero-extension
tracking with static liveness analysis to correctly infer zext_dst
and prevent missing zero-extensions on architectures like s390x.
Link: https://lore.kernel.org/bpf/CAGKGUv=sOuqQtA1Ub-5JXfA4FPosJFYKAQE4B79cK+P1erxqtg@mail.gmail.com/
> diff --git a/kernel/bpf/liveness.c b/kernel/bpf/liveness.c
> index c996b8a03e792..ea002550671a8 100644
> --- a/kernel/bpf/liveness.c
> +++ b/kernel/bpf/liveness.c
> @@ -2317,9 +2318,18 @@ int bpf_compute_live_registers(struct bpf_verifier_env *env)
> }
>
> for (i = 0; i < insn_cnt; ++i) {
> + int def32 = bpf_insn_def32(&insns[i]);
> + u32 out = state[i].out;
> u32 in = state[i].in;
>
> insn_aux[i].live_regs_before = mask_lo(in) | mask_hi(in);
> + /*
> + * On architectures where 32-bit operations do not reset upper halves
> + * of the registers, the verifier needs to zero extend a destination
> + * register if an instruction defines a 32-bit subregister and the
> + * upper half of that register is alive after the instruction.
> + */
> + insn_aux[i].zext_dst = def32 >= 0 && (mask_hi(out) & BIT(def32));
[Severity: Critical]
Does this code correctly evaluate liveness for 64-bit conditional jumps?
The new zext_dst logic relies on mask_hi(out) accurately reflecting if the
upper half of a register is alive.
However, looking at compute_insn_live_regs() in kernel/bpf/liveness.c for
conditional jumps:
const u8 class = BPF_CLASS(insn->code);
const u8 code = BPF_OP(insn->code);
...
case BPF_JMP:
case BPF_JMP32:
switch (code) {
...
default:
def = 0;
if (BPF_SRC(insn->code) == BPF_K)
use = dst;
else
use = dst | (code == BPF_JMP32 ? src : src32);
}
Can the code variable ever equal BPF_JMP32?
BPF_OP() extracts the operation code (which is a multiple of 16), while
BPF_JMP32 is a class (0x06). This means the check code == BPF_JMP32 evaluates
to false, and the source register usage always falls back to src32, even for
64-bit jumps (BPF_JMP).
If a 32-bit operation defines a register, and it is followed by a 64-bit
conditional jump using that register as a source with no other uses of the
upper 32 bits, the upper half won't be marked as alive.
As a result, zext_dst wouldn't be set, which could lead to the JIT skipping
the mandatory zero extension. This would cause the 64-bit jump to compare
against uninitialized garbage in the upper bits, potentially allowing
out-of-bounds access.
Should this check use class == BPF_JMP32 instead?
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260731-static-zext-v1-0-98a4dc73e94b@gmail.com?part=3
next prev parent reply other threads:[~2026-07-31 19:26 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 19:07 [PATCH bpf-next 0/5] bpf: infer zext_dst based on static register liveness analysis Eduard Zingerman
2026-07-31 19:07 ` [PATCH bpf-next 1/5] bpf: do not print a newline after disassembly in bpf_verbose_insn() Eduard Zingerman
2026-07-31 20:24 ` bot+bpf-ci
2026-07-31 21:12 ` Eduard Zingerman
2026-07-31 19:07 ` [PATCH bpf-next 2/5] bpf: track upper 32-bit register halves' liveness in compute_live_registers() Eduard Zingerman
2026-07-31 19:18 ` sashiko-bot
2026-07-31 19:07 ` [PATCH bpf-next 3/5] bpf: infer zext_dst based on static register liveness analysis Eduard Zingerman
2026-07-31 19:26 ` sashiko-bot [this message]
2026-07-31 21:17 ` Eduard Zingerman
2026-07-31 19:07 ` [PATCH bpf-next 4/5] bpf: simplify the bpf_is_reg64() signature Eduard Zingerman
2026-07-31 19:18 ` sashiko-bot
2026-07-31 20:09 ` bot+bpf-ci
2026-07-31 19:07 ` [PATCH bpf-next 5/5] selftests/bpf: verify zext_dst annotations for various instructions Eduard Zingerman
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=20260731192635.8B8111F00AC4@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=eddyz87@gmail.com \
--cc=sashiko-reviews@lists.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.