Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: Fix a kernel verifier crash in stacksafe()

Daniel Hodges reported a kernel verifier crash when playing with sched-ext.
Further investigation shows that the crash is due to invalid memory access
in stacksafe(). More specifically, it is the following code:

if (exact != NOT_EXACT &&
old->stack[spi].slot_type[i % BPF_REG_SIZE] !=
cur->stack[spi].slot_type[i % BPF_REG_SIZE])
return false;

The 'i' iterates old->allocated_stack.
If cur->allocated_stack < old->allocated_stack the out-of-bound
access will happen.

To fix the issue add 'i >= cur->allocated_stack' check such that if
the condition is true, stacksafe() should fail. Otherwise,
cur->stack[spi].slot_type[i % BPF_REG_SIZE] memory access is legal.

Fixes: 2793a8b015f7 ("bpf: exact states comparison for iterator convergence checks")
Cc: Eduard Zingerman <eddyz87@gmail.com>
Reported-by: Daniel Hodges <hodgesd@meta.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/r/20240812214847.213612-1-yonghong.song@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Yonghong Song and committed by
Alexei Starovoitov
bed2eb96 fdad456c

+3 -2
+3 -2
kernel/bpf/verifier.c
··· 16884 16884 spi = i / BPF_REG_SIZE; 16885 16885 16886 16886 if (exact != NOT_EXACT && 16887 - old->stack[spi].slot_type[i % BPF_REG_SIZE] != 16888 - cur->stack[spi].slot_type[i % BPF_REG_SIZE]) 16887 + (i >= cur->allocated_stack || 16888 + old->stack[spi].slot_type[i % BPF_REG_SIZE] != 16889 + cur->stack[spi].slot_type[i % BPF_REG_SIZE])) 16889 16890 return false; 16890 16891 16891 16892 if (!(old->stack[spi].spilled_ptr.live & REG_LIVE_READ)