Skip to content

Commit

Permalink
bpf: Refactor and streamline bounds check into helper
Browse files Browse the repository at this point in the history
[ Upstream commit 073815b ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
borkmann authored and gregkh committed Apr 28, 2021
1 parent d1b725e commit 2f5cfb7
Showing 1 changed file with 33 additions and 16 deletions.
49 changes: 33 additions & 16 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -5938,6 +5938,37 @@ static int check_stack_access_for_ptr_arithmetic(
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.
* Caller should also handle BPF_MOV case separately.
Expand Down Expand Up @@ -6163,22 +6194,8 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
__reg_deduce_bounds(dst_reg);
__reg_bound_offset(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) {
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;
} 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;
}
}
if (sanitize_check_bounds(env, insn, dst_reg) < 0)
return -EACCES;

return 0;
}
Expand Down

0 comments on commit 2f5cfb7

Please sign in to comment.