Skip to content

Commit 876d1ce

Browse files
borkmanngregkh
authored andcommitted
bpf: Refactor and streamline bounds check into helper
commit 073815b upstream. 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> [fllinden@amazon.com: backport to 5.4] Signed-off-by: Frank van der Linden <fllinden@amazon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 4158e5f commit 876d1ce

1 file changed

Lines changed: 37 additions & 17 deletions

File tree

kernel/bpf/verifier.c

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4448,6 +4448,41 @@ static int sanitize_err(struct bpf_verifier_env *env,
44484448
return -EACCES;
44494449
}
44504450

4451+
static int sanitize_check_bounds(struct bpf_verifier_env *env,
4452+
const struct bpf_insn *insn,
4453+
const struct bpf_reg_state *dst_reg)
4454+
{
4455+
u32 dst = insn->dst_reg;
4456+
4457+
/* For unprivileged we require that resulting offset must be in bounds
4458+
* in order to be able to sanitize access later on.
4459+
*/
4460+
if (env->allow_ptr_leaks)
4461+
return 0;
4462+
4463+
switch (dst_reg->type) {
4464+
case PTR_TO_STACK:
4465+
if (check_stack_access(env, dst_reg, dst_reg->off +
4466+
dst_reg->var_off.value, 1)) {
4467+
verbose(env, "R%d stack pointer arithmetic goes out of range, "
4468+
"prohibited for !root\n", dst);
4469+
return -EACCES;
4470+
}
4471+
break;
4472+
case PTR_TO_MAP_VALUE:
4473+
if (check_map_access(env, dst, dst_reg->off, 1, false)) {
4474+
verbose(env, "R%d pointer arithmetic of map value goes out of range, "
4475+
"prohibited for !root\n", dst);
4476+
return -EACCES;
4477+
}
4478+
break;
4479+
default:
4480+
break;
4481+
}
4482+
4483+
return 0;
4484+
}
4485+
44514486
/* Handles arithmetic on a pointer and a scalar: computes new min/max and var_off.
44524487
* Caller should also handle BPF_MOV case separately.
44534488
* If we return -EACCES, caller may want to try again treating pointer as a
@@ -4664,23 +4699,8 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
46644699
__reg_deduce_bounds(dst_reg);
46654700
__reg_bound_offset(dst_reg);
46664701

4667-
/* For unprivileged we require that resulting offset must be in bounds
4668-
* in order to be able to sanitize access later on.
4669-
*/
4670-
if (!env->allow_ptr_leaks) {
4671-
if (dst_reg->type == PTR_TO_MAP_VALUE &&
4672-
check_map_access(env, dst, dst_reg->off, 1, false)) {
4673-
verbose(env, "R%d pointer arithmetic of map value goes out of range, "
4674-
"prohibited for !root\n", dst);
4675-
return -EACCES;
4676-
} else if (dst_reg->type == PTR_TO_STACK &&
4677-
check_stack_access(env, dst_reg, dst_reg->off +
4678-
dst_reg->var_off.value, 1)) {
4679-
verbose(env, "R%d stack pointer arithmetic goes out of range, "
4680-
"prohibited for !root\n", dst);
4681-
return -EACCES;
4682-
}
4683-
}
4702+
if (sanitize_check_bounds(env, insn, dst_reg) < 0)
4703+
return -EACCES;
46844704

46854705
return 0;
46864706
}

0 commit comments

Comments
 (0)