summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKumar Kartikeya Dwivedi <memxor@gmail.com>2026-08-20 04:20:18 +0200
committerDaniel Borkmann <daniel@iogearbox.net>2026-08-20 18:45:44 +0200
commit37e5c4f4d2856290b1c56e573ced91dcd88db8ec (patch)
treea78ab756f8d1aa28ba45a08141158ff7d5f57f40
parentc7a2a3618290594867b4829900b434704ab31dbc (diff)
bpf: Reject invalid LDSX instruction in disassembly
The signed-load mnemonic table has entries for byte, half-word, and word loads because BPF_MEMSX does not support double-word loads. A BPF_MEMSX | BPF_DW instruction nevertheless selects index 3, past the end of this table. Program Structure diagnostics can disassemble a malformed instruction before check_and_resolve_insns() rejects its opcode. Placing the invalid signed double-word load at the end of a program therefore triggers an out-of-bounds access while reporting subprogram fallthrough. Treat signed double-word loads as invalid in the disassembler and use the existing BUG_ldx fallback instead. Fixes: a8f427835394 ("bpf: Report Program Structure CFG errors") Reported-by: syzbot+3544d9b2a9206be8ba37@syzkaller.appspotmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://lore.kernel.org/bpf/20260820022020.3450479-2-memxor@gmail.com
-rw-r--r--kernel/bpf/disasm.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/kernel/bpf/disasm.c b/kernel/bpf/disasm.c
index 50b3ca5149a0..b1a3fbe3fda5 100644
--- a/kernel/bpf/disasm.c
+++ b/kernel/bpf/disasm.c
@@ -295,7 +295,8 @@ void print_bpf_insn(const struct bpf_insn_cbs *cbs,
verbose(cbs->private_data, "BUG_st_%02x", insn->code);
}
} else if (class == BPF_LDX) {
- if (BPF_MODE(insn->code) != BPF_MEM && BPF_MODE(insn->code) != BPF_MEMSX) {
+ if ((BPF_MODE(insn->code) != BPF_MEM && BPF_MODE(insn->code) != BPF_MEMSX) ||
+ (BPF_MODE(insn->code) == BPF_MEMSX && BPF_SIZE(insn->code) == BPF_DW)) {
verbose(cbs->private_data, "BUG_ldx_%02x", insn->code);
return;
}