Commit 3cd5c890 authored by Puranjay Mohan's avatar Puranjay Mohan Committed by Alexei Starovoitov
Browse files

bpf: Let the verifier assign ids on stack fills



The next commit will allow clearing of scalar ids if no other
register/stack slot has that id. This is because if only one register
has a unique id, it can't participate in bounds propagation and is
equivalent to having no id.

But if the id of a stack slot is cleared by clear_singular_ids() in the
next commit, reading that stack slot into a register will not establish
a link because the stack slot's id is cleared.

This can happen in a situation where a register is spilled and later
loses its id due to a multiply operation (for example) and then the
stack slot's id becomes singular and can be cleared.

Make sure that scalar stack slots have an id before we read them into a
register.

Acked-by: default avatarEduard Zingerman <eddyz87@gmail.com>
Signed-off-by: default avatarPuranjay Mohan <puranjay@kernel.org>
Link: https://lore.kernel.org/r/20260203165102.2302462-2-puranjay@kernel.org


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent d95d76aa
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -5518,6 +5518,12 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
				 */
				s32 subreg_def = state->regs[dst_regno].subreg_def;
				if (env->bpf_capable && size == 4 && spill_size == 4 &&
				    get_reg_width(reg) <= 32)
					/* Ensure stack slot has an ID to build a relation
					 * with the destination register on fill.
					 */
					assign_scalar_id_before_mov(env, reg);
				copy_register_state(&state->regs[dst_regno], reg);
				state->regs[dst_regno].subreg_def = subreg_def;
@@ -5563,6 +5569,11 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
			}
		} else if (dst_regno >= 0) {
			/* restore register state from stack */
			if (env->bpf_capable)
				/* Ensure stack slot has an ID to build a relation
				 * with the destination register on fill.
				 */
				assign_scalar_id_before_mov(env, reg);
			copy_register_state(&state->regs[dst_regno], reg);
			/* mark reg as written since spilled pointer state likely
			 * has its liveness marks cleared by is_state_visited()