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

bpf: Assign ID to scalars on spill

Currently, when a scalar bounded register is spilled to the stack, its
ID is preserved, but only if was already assigned, i.e. if this register
was MOVed before.

Assign an ID on spill if none is set, so that equal scalars could be
tracked if a register is spilled to the stack and filled into another
register.

One test is adjusted to reflect the change in register IDs.

Signed-off-by: Maxim Mikityanskiy <maxim@isovalent.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20240108205209.838365-9-maxtram95@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Maxim Mikityanskiy and committed by
Alexei Starovoitov
8ecfc371 87e51ac6

+11 -5
+7 -1
kernel/bpf/verifier.c
··· 4505 4505 4506 4506 mark_stack_slot_scratched(env, spi); 4507 4507 if (reg && !(off % BPF_REG_SIZE) && register_is_bounded(reg) && env->bpf_capable) { 4508 + bool reg_value_fits; 4509 + 4510 + reg_value_fits = get_reg_width(reg) <= BITS_PER_BYTE * size; 4511 + /* Make sure that reg had an ID to build a relation on spill. */ 4512 + if (reg_value_fits) 4513 + assign_scalar_id_before_mov(env, reg); 4508 4514 save_register_state(env, state, spi, reg, size); 4509 4515 /* Break the relation on a narrowing spill. */ 4510 - if (get_reg_width(reg) > BITS_PER_BYTE * size) 4516 + if (!reg_value_fits) 4511 4517 state->stack[spi].spilled_ptr.id = 0; 4512 4518 } else if (!reg && !(off % BPF_REG_SIZE) && is_bpf_st_mem(insn) && 4513 4519 insn->imm != 0 && env->bpf_capable) {
+1 -1
tools/testing/selftests/bpf/progs/verifier_direct_packet_access.c
··· 568 568 569 569 SEC("tc") 570 570 __description("direct packet access: test23 (x += pkt_ptr, 4)") 571 - __failure __msg("invalid access to packet, off=0 size=8, R5(id=2,off=0,r=0)") 571 + __failure __msg("invalid access to packet, off=0 size=8, R5(id=3,off=0,r=0)") 572 572 __flag(BPF_F_ANY_ALIGNMENT) 573 573 __naked void test23_x_pkt_ptr_4(void) 574 574 {
+3 -3
tools/testing/selftests/bpf/verifier/precise.c
··· 183 183 .prog_type = BPF_PROG_TYPE_XDP, 184 184 .flags = BPF_F_TEST_STATE_FREQ, 185 185 .errstr = "mark_precise: frame0: last_idx 7 first_idx 7\ 186 - mark_precise: frame0: parent state regs=r4 stack=:\ 186 + mark_precise: frame0: parent state regs=r4 stack=-8:\ 187 187 mark_precise: frame0: last_idx 6 first_idx 4\ 188 - mark_precise: frame0: regs=r4 stack= before 6: (b7) r0 = -1\ 189 - mark_precise: frame0: regs=r4 stack= before 5: (79) r4 = *(u64 *)(r10 -8)\ 188 + mark_precise: frame0: regs=r4 stack=-8 before 6: (b7) r0 = -1\ 189 + mark_precise: frame0: regs=r4 stack=-8 before 5: (79) r4 = *(u64 *)(r10 -8)\ 190 190 mark_precise: frame0: regs= stack=-8 before 4: (7b) *(u64 *)(r3 -8) = r0\ 191 191 mark_precise: frame0: parent state regs=r0 stack=:\ 192 192 mark_precise: frame0: last_idx 3 first_idx 3\