Skip to content

Commit dbd8d22

Browse files
kkdwvdAlexei Starovoitov
authored andcommitted
bpf: Wrap register invalidation with a helper
Typically, verifier should use env->allow_ptr_leaks when invaliding registers for users that don't have CAP_PERFMON or CAP_SYS_ADMIN to avoid leaking the pointer value. This is similar in spirit to c67cae5 ("bpf: Tighten ptr_to_btf_id checks."). In a lot of the existing checks, we know the capabilities are present, hence we don't do the check. Instead of being inconsistent in the application of the check, wrap the action of invalidating a register into a helper named 'mark_invalid_reg' and use it in a uniform fashion to replace open coded invalidation operations, so that the check is always made regardless of the call site and we don't have to remember whether it needs to be done or not for each case. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20230221200646.2500777-7-memxor@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent da03e43 commit dbd8d22

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

kernel/bpf/verifier.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,14 @@ static int unmark_stack_slots_dynptr(struct bpf_verifier_env *env, struct bpf_re
895895
static void __mark_reg_unknown(const struct bpf_verifier_env *env,
896896
struct bpf_reg_state *reg);
897897

898+
static void mark_reg_invalid(const struct bpf_verifier_env *env, struct bpf_reg_state *reg)
899+
{
900+
if (!env->allow_ptr_leaks)
901+
__mark_reg_not_init(env, reg);
902+
else
903+
__mark_reg_unknown(env, reg);
904+
}
905+
898906
static int destroy_if_dynptr_stack_slot(struct bpf_verifier_env *env,
899907
struct bpf_func_state *state, int spi)
900908
{
@@ -934,12 +942,8 @@ static int destroy_if_dynptr_stack_slot(struct bpf_verifier_env *env,
934942
/* Dynptr slices are only PTR_TO_MEM_OR_NULL and PTR_TO_MEM */
935943
if (dreg->type != (PTR_TO_MEM | PTR_MAYBE_NULL) && dreg->type != PTR_TO_MEM)
936944
continue;
937-
if (dreg->dynptr_id == dynptr_id) {
938-
if (!env->allow_ptr_leaks)
939-
__mark_reg_not_init(env, dreg);
940-
else
941-
__mark_reg_unknown(env, dreg);
942-
}
945+
if (dreg->dynptr_id == dynptr_id)
946+
mark_reg_invalid(env, dreg);
943947
}));
944948

945949
/* Do not release reference state, we are destroying dynptr on stack,
@@ -7384,7 +7388,7 @@ static void clear_all_pkt_pointers(struct bpf_verifier_env *env)
73847388

73857389
bpf_for_each_reg_in_vstate(env->cur_state, state, reg, ({
73867390
if (reg_is_pkt_pointer_any(reg))
7387-
__mark_reg_unknown(env, reg);
7391+
mark_reg_invalid(env, reg);
73887392
}));
73897393
}
73907394

@@ -7429,12 +7433,8 @@ static int release_reference(struct bpf_verifier_env *env,
74297433
return err;
74307434

74317435
bpf_for_each_reg_in_vstate(env->cur_state, state, reg, ({
7432-
if (reg->ref_obj_id == ref_obj_id) {
7433-
if (!env->allow_ptr_leaks)
7434-
__mark_reg_not_init(env, reg);
7435-
else
7436-
__mark_reg_unknown(env, reg);
7437-
}
7436+
if (reg->ref_obj_id == ref_obj_id)
7437+
mark_reg_invalid(env, reg);
74387438
}));
74397439

74407440
return 0;
@@ -7447,7 +7447,7 @@ static void invalidate_non_owning_refs(struct bpf_verifier_env *env)
74477447

74487448
bpf_for_each_reg_in_vstate(env->cur_state, unused, reg, ({
74497449
if (type_is_non_owning_ref(reg->type))
7450-
__mark_reg_unknown(env, reg);
7450+
mark_reg_invalid(env, reg);
74517451
}));
74527452
}
74537453

0 commit comments

Comments
 (0)