bpf: Refactor and streamline bounds check into helper
Move the bounds check in adjust_ptr_min_max_vals() into a small helper named sanitize_check_bounds() in order to simplify the former a bit. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: John Fastabend <john.fastabend@gmail.com> Acked-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
a6aaece00a
commit
073815b756
@ -6075,6 +6075,37 @@ static int check_stack_access_for_ptr_arithmetic(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sanitize_check_bounds(struct bpf_verifier_env *env,
|
||||||
|
const struct bpf_insn *insn,
|
||||||
|
const struct bpf_reg_state *dst_reg)
|
||||||
|
{
|
||||||
|
u32 dst = insn->dst_reg;
|
||||||
|
|
||||||
|
/* For unprivileged we require that resulting offset must be in bounds
|
||||||
|
* in order to be able to sanitize access later on.
|
||||||
|
*/
|
||||||
|
if (env->bypass_spec_v1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (dst_reg->type) {
|
||||||
|
case PTR_TO_STACK:
|
||||||
|
if (check_stack_access_for_ptr_arithmetic(env, dst, dst_reg,
|
||||||
|
dst_reg->off + dst_reg->var_off.value))
|
||||||
|
return -EACCES;
|
||||||
|
break;
|
||||||
|
case PTR_TO_MAP_VALUE:
|
||||||
|
if (check_map_access(env, dst, dst_reg->off, 1, false)) {
|
||||||
|
verbose(env, "R%d pointer arithmetic of map value goes out of range, "
|
||||||
|
"prohibited for !root\n", dst);
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Handles arithmetic on a pointer and a scalar: computes new min/max and var_off.
|
/* Handles arithmetic on a pointer and a scalar: computes new min/max and var_off.
|
||||||
* Caller should also handle BPF_MOV case separately.
|
* Caller should also handle BPF_MOV case separately.
|
||||||
@ -6300,22 +6331,8 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
|
|||||||
__reg_deduce_bounds(dst_reg);
|
__reg_deduce_bounds(dst_reg);
|
||||||
__reg_bound_offset(dst_reg);
|
__reg_bound_offset(dst_reg);
|
||||||
|
|
||||||
/* For unprivileged we require that resulting offset must be in bounds
|
if (sanitize_check_bounds(env, insn, dst_reg) < 0)
|
||||||
* in order to be able to sanitize access later on.
|
|
||||||
*/
|
|
||||||
if (!env->bypass_spec_v1) {
|
|
||||||
if (dst_reg->type == PTR_TO_MAP_VALUE &&
|
|
||||||
check_map_access(env, dst, dst_reg->off, 1, false)) {
|
|
||||||
verbose(env, "R%d pointer arithmetic of map value goes out of range, "
|
|
||||||
"prohibited for !root\n", dst);
|
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
} else if (dst_reg->type == PTR_TO_STACK &&
|
|
||||||
check_stack_access_for_ptr_arithmetic(
|
|
||||||
env, dst, dst_reg, dst_reg->off +
|
|
||||||
dst_reg->var_off.value)) {
|
|
||||||
return -EACCES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user