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

Configure Feed

Select the types of activity you want to include in your feed.

bpf: Fix variable length stack write over spilled pointers

Scrub slots if variable-offset stack write goes over spilled pointers.
Otherwise is_spilled_reg() may == true && spilled_ptr.type == NOT_INIT
and valid program is rejected by check_stack_read_fixed_off()
with obscure "invalid size of register fill" message.

Fixes: 01f810ace9ed ("bpf: Allow variable-offset stack access")
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260324215938.81733-1-alexei.starovoitov@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

+20 -8
+20 -8
kernel/bpf/verifier.c
··· 5251 5251 } 5252 5252 } 5253 5253 5254 + static void scrub_special_slot(struct bpf_func_state *state, int spi) 5255 + { 5256 + int i; 5257 + 5258 + /* regular write of data into stack destroys any spilled ptr */ 5259 + state->stack[spi].spilled_ptr.type = NOT_INIT; 5260 + /* Mark slots as STACK_MISC if they belonged to spilled ptr/dynptr/iter. */ 5261 + if (is_stack_slot_special(&state->stack[spi])) 5262 + for (i = 0; i < BPF_REG_SIZE; i++) 5263 + scrub_spilled_slot(&state->stack[spi].slot_type[i]); 5264 + } 5265 + 5254 5266 /* check_stack_{read,write}_fixed_off functions track spill/fill of registers, 5255 5267 * stack boundary and alignment are checked in check_mem_access() 5256 5268 */ ··· 5360 5348 } else { 5361 5349 u8 type = STACK_MISC; 5362 5350 5363 - /* regular write of data into stack destroys any spilled ptr */ 5364 - state->stack[spi].spilled_ptr.type = NOT_INIT; 5365 - /* Mark slots as STACK_MISC if they belonged to spilled ptr/dynptr/iter. */ 5366 - if (is_stack_slot_special(&state->stack[spi])) 5367 - for (i = 0; i < BPF_REG_SIZE; i++) 5368 - scrub_spilled_slot(&state->stack[spi].slot_type[i]); 5351 + scrub_special_slot(state, spi); 5369 5352 5370 5353 /* when we zero initialize stack slots mark them as such */ 5371 5354 if ((reg && register_is_null(reg)) || ··· 5483 5476 } 5484 5477 } 5485 5478 5486 - /* Erase all other spilled pointers. */ 5487 - state->stack[spi].spilled_ptr.type = NOT_INIT; 5479 + /* 5480 + * Scrub slots if variable-offset stack write goes over spilled pointers. 5481 + * Otherwise is_spilled_reg() may == true && spilled_ptr.type == NOT_INIT 5482 + * and valid program is rejected by check_stack_read_fixed_off() 5483 + * with obscure "invalid size of register fill" message. 5484 + */ 5485 + scrub_special_slot(state, spi); 5488 5486 5489 5487 /* Update the slot type. */ 5490 5488 new_type = STACK_MISC;