aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/verifier.c
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2019-01-02 18:58:32 -0500
committerAlexei Starovoitov <ast@kernel.org>2019-01-02 19:01:24 -0500
commit9d7eceede769f90b66cfa06ad5b357140d5141ed (patch)
treecf1e780e43ad0667e2ef04ae14ce5bf98a47bb97 /kernel/bpf/verifier.c
parente4298d25830a866cc0f427d4bccb858e76715859 (diff)
bpf: restrict unknown scalars of mixed signed bounds for unprivileged
For unknown scalars of mixed signed bounds, meaning their smin_value is negative and their smax_value is positive, we need to reject arithmetic with pointer to map value. For unprivileged the goal is to mask every map pointer arithmetic and this cannot reliably be done when it is unknown at verification time whether the scalar value is negative or positive. Given this is a corner case, the likelihood of breaking should be very small. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'kernel/bpf/verifier.c')
-rw-r--r--kernel/bpf/verifier.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 9ac205d1b8b7..eebbc03e5af2 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3081,8 +3081,8 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
3081 smin_ptr = ptr_reg->smin_value, smax_ptr = ptr_reg->smax_value; 3081 smin_ptr = ptr_reg->smin_value, smax_ptr = ptr_reg->smax_value;
3082 u64 umin_val = off_reg->umin_value, umax_val = off_reg->umax_value, 3082 u64 umin_val = off_reg->umin_value, umax_val = off_reg->umax_value,
3083 umin_ptr = ptr_reg->umin_value, umax_ptr = ptr_reg->umax_value; 3083 umin_ptr = ptr_reg->umin_value, umax_ptr = ptr_reg->umax_value;
3084 u32 dst = insn->dst_reg, src = insn->src_reg;
3084 u8 opcode = BPF_OP(insn->code); 3085 u8 opcode = BPF_OP(insn->code);
3085 u32 dst = insn->dst_reg;
3086 3086
3087 dst_reg = &regs[dst]; 3087 dst_reg = &regs[dst];
3088 3088
@@ -3115,6 +3115,13 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
3115 verbose(env, "R%d pointer arithmetic on %s prohibited\n", 3115 verbose(env, "R%d pointer arithmetic on %s prohibited\n",
3116 dst, reg_type_str[ptr_reg->type]); 3116 dst, reg_type_str[ptr_reg->type]);
3117 return -EACCES; 3117 return -EACCES;
3118 case PTR_TO_MAP_VALUE:
3119 if (!env->allow_ptr_leaks && !known && (smin_val < 0) != (smax_val < 0)) {
3120 verbose(env, "R%d has unknown scalar with mixed signed bounds, pointer arithmetic with it prohibited for !root\n",
3121 off_reg == dst_reg ? dst : src);
3122 return -EACCES;
3123 }
3124 /* fall-through */
3118 default: 3125 default:
3119 break; 3126 break;
3120 } 3127 }