Skip to content

Commit 261f466

Browse files
kkdwvdAlexei Starovoitov
authored andcommitted
bpf: Clobber stack slot when writing over spilled PTR_TO_BTF_ID
When support was added for spilled PTR_TO_BTF_ID to be accessed by helper memory access, the stack slot was not overwritten to STACK_MISC (and that too is only safe when env->allow_ptr_leaks is true). This means that helpers who take ARG_PTR_TO_MEM and write to it may essentially overwrite the value while the verifier continues to track the slot for spilled register. This can cause issues when PTR_TO_BTF_ID is spilled to stack, and then overwritten by helper write access, which can then be passed to BPF helpers or kfuncs. Handle this by falling back to the case introduced in a later commit, which will also handle PTR_TO_BTF_ID along with other pointer types, i.e. cd17d38 ("bpf: Permits pointers on stack for helper calls"). Finally, include a comment on why REG_LIVE_WRITTEN is not being set when clobber is set to true. In short, the reason is that while when clobber is unset, we know that we won't be writing, when it is true, we *may* write to any of the stack slots in that range. It may be a partial or complete write, to just one or many stack slots. We cannot be sure, hence to be conservative, we leave things as is and never set REG_LIVE_WRITTEN for any stack slot. However, clobber still needs to reset them to STACK_MISC assuming writes happened. However read marks still need to be propagated upwards from liveness point of view, as parent stack slot's contents may still continue to matter to child states. Cc: Yonghong Song <yhs@meta.com> Fixes: 1d68f22 ("bpf: Handle spilled PTR_TO_BTF_ID properly when checking stack_boundary") Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20221103191013.1236066-4-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 23da464 commit 261f466

1 file changed

Lines changed: 5 additions & 4 deletions

File tree

kernel/bpf/verifier.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5154,10 +5154,6 @@ static int check_stack_range_initialized(
51545154
goto mark;
51555155
}
51565156

5157-
if (is_spilled_reg(&state->stack[spi]) &&
5158-
base_type(state->stack[spi].spilled_ptr.type) == PTR_TO_BTF_ID)
5159-
goto mark;
5160-
51615157
if (is_spilled_reg(&state->stack[spi]) &&
51625158
(state->stack[spi].spilled_ptr.type == SCALAR_VALUE ||
51635159
env->allow_ptr_leaks)) {
@@ -5188,6 +5184,11 @@ static int check_stack_range_initialized(
51885184
mark_reg_read(env, &state->stack[spi].spilled_ptr,
51895185
state->stack[spi].spilled_ptr.parent,
51905186
REG_LIVE_READ64);
5187+
/* We do not set REG_LIVE_WRITTEN for stack slot, as we can not
5188+
* be sure that whether stack slot is written to or not. Hence,
5189+
* we must still conservatively propagate reads upwards even if
5190+
* helper may write to the entire memory range.
5191+
*/
51915192
}
51925193
return update_stack_depth(env, state, min_off);
51935194
}

0 commit comments

Comments
 (0)