Skip to content

"bpf: Reject negative const offsets for buffer pointers" test on v6.18#9

Open
shunghsiyu wants to merge 2 commits into
kernel-patches:linux-6.18.yfrom
shunghsiyu:linux-6.18.y
Open

"bpf: Reject negative const offsets for buffer pointers" test on v6.18#9
shunghsiyu wants to merge 2 commits into
kernel-patches:linux-6.18.yfrom
shunghsiyu:linux-6.18.y

Conversation

@shunghsiyu

Copy link
Copy Markdown
Collaborator

borkmann and others added 2 commits July 6, 2026 15:19
commit 48d83d9 upstream.

aarch64_insn_gen_cond_branch_imm() calls label_imm_common() to
compute a 19-bit signed byte offset for a conditional branch,
but unlike its siblings aarch64_insn_gen_branch_imm() and
aarch64_insn_gen_comp_branch_imm(), it does not check whether
label_imm_common() returned its out-of-range sentinel (range)
before feeding the value to aarch64_insn_encode_immediate().

aarch64_insn_encode_immediate() unconditionally masks the value
with the 19-bit field mask, so an offset that was rejected by
label_imm_common() gets silently truncated. With the sentinel
value SZ_1M, the resulting field ends up with bit 18 (the sign
bit of the 19-bit signed displacement) set, and the CPU decodes
it as a ~1 MiB *backward* branch, producing an incorrectly
targeted B.cond instruction. For code-gen locations like the
emit_bpf_tail_call() this function is the only barrier between
an overflowing displacement and a silently miscompiled branch.

Fix it by returning AARCH64_BREAK_FAULT when the offset is out
of range, so callers see a loud failure instead of a silently
misencoded branch. validate_code() scans the generated image
for any AARCH64_BREAK_FAULT and then lets the JIT fail.

Fixes: 345e0d3 ("arm64: introduce aarch64_insn_gen_cond_branch_imm()")
Fixes: c94ae4f ("arm64: insn: remove BUG_ON from codegen")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Puranjay Mohan <puranjay@kernel.org>
Link: https://lore.kernel.org/r/20260415121403.639619-1-daniel@iogearbox.net
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Shung-Hsi Yu <shung-hsi.yu@suse.com>
THIS ONLY CONTAINS THE TEST.

The verifier rejects variable offsets for PTR_TO_TP_BUFFER and PTR_TO_BUF
accesses, but it currently accepts a constant negative offset produced by
pointer arithmetic.

For example, a raw tracepoint writable program can load ctx[0] as a
PTR_TO_TP_BUFFER, move it by -8, and then read from the adjusted pointer.
The register is still tracked as tp_buffer(imm=-8), but the access is
before the tracepoint writable buffer base and should be rejected.

Check the signed effective buffer offset before updating max_tp_access or
other buffer max access accounting. Reject negative effective offsets and
use the checked end offset for max access accounting.

Add a verifier test that rejects a raw tracepoint writable program using a
negative constant offset.

Fixes: 9df1c28 ("bpf: add writable context for raw tracepoints")
Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com>
@kernel-patches-daemon-bpf kernel-patches-daemon-bpf Bot force-pushed the linux-6.18.y branch 4 times, most recently from a49dbd9 to 46a428c Compare July 9, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants