From 78a3119f3b1545e0113f2621cd0d1822e6e2d0bd Mon Sep 17 00:00:00 2001 From: Steve Grubb Date: Tue, 6 Oct 2026 11:53:44 -0400 Subject: [PATCH] scmp_bpf_sim: Don't overread struct seccomp_data In the BPF_LD+BPF_W+BPF_ABS case of bpf_execute, a check is done of k to ensure it is < BPF_SYSCALL_MAX which is 64. The way it is written, passing a value of 63 is legal and passes the check. But it is going to read sizeof(unint32_t) or 4 bytes meaning a read from offset 63 to 66. This is beyond struct seccomp_data's end. Condition the check by subtracting sizeof(unint32_t) to allow the right size offset. Now if someone passes offset 60, it is equal to the limit and allows reading bytes 60 - 63 which fits within struct seccomp_data. scmp_bpf_sim doesn't appear to be shipped and I don't think anyone can use this flaw to any effect as it crosses no trust boundaries, there is no demonstrated write, code execution, privilege escalation, or useful information disclosure. Just undefined behavior. Signed-off-by: Steve Grubb --- tools/scmp_bpf_sim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/scmp_bpf_sim.c b/tools/scmp_bpf_sim.c index fb7bd2d1..ddb4176c 100644 --- a/tools/scmp_bpf_sim.c +++ b/tools/scmp_bpf_sim.c @@ -181,7 +181,8 @@ static void bpf_execute(const struct bpf_program *prg, switch (code) { case BPF_LD+BPF_W+BPF_ABS: - if (k < BPF_SYSCALL_MAX) { + /* Subtract 4 bytes so we don't go past the end */ + if (k <= BPF_SYSCALL_MAX - sizeof(uint32_t)) { uint32_t val; memcpy(&val, &sys_data_b[k], sizeof(val)); state.acc = ttoh32(arch, val);