This patch re-introduces protection against the size of access to stack memory being negative; the access size can appear negative as a result of overflowing its signed int representation (the respective function arguments is sometimes converted from a u32 and u64 without any overflow checking), and causes out-of-bounds array accesses in check_stack_range_initialized(). This patch causes the verification of a program with such a non-sensical access size to fail. This check used to exist in a more indirect way, but was inadvertendly removed in a833a17a. This omission was found by syzkaller. I have failed to actually create a program that triggers the issue (different other protections kick in for different code paths). The syzkaller program is opaque and I failed to fully decipher it; from what I gather, it declares a map with a huge value type (0x80000001 bytes, which is INT_MAX + 2), and somehow calls a helper (bpf_map_peek_elem), and manages to pass to it a pointer to the stack while, at the same time, the size of values in this map is being used as the "access size". Fixes: a833a17a ("bpf: Fix verification of indirect var-off stack access") Reported-by: syzbot+33f4297b5f927648741a@xxxxxxxxxxxxxxxxxxxxxxxxx Closes: https://lore.kernel.org/bpf/CAADnVQLORV5PT0iTAhRER+iLBTkByCYNBYyvBSgjN1T31K+gOw@xxxxxxxxxxxxxx/ --- kernel/bpf/verifier.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 0bfc0050db28..2019d6177969 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -6701,6 +6701,8 @@ static int check_stack_access_within_bounds( err = check_stack_slot_within_bounds(env, min_off, state, type); if (!err && max_off > 0) err = -EINVAL; /* out of stack access into non-negative offsets */ + if (!err && access_size < 0) + err = -EINVAL; /* invalid negative access size; integer overflow? */ if (err) { if (tnum_is_const(reg->var_off)) { -- 2.40.1