Commit dfeb8f4c authored by Alexei Starovoitov's avatar Alexei Starovoitov

Merge branch 'verifier-fixes'

Daniel Borkmann says:

====================
The series contains two fixes in BPF core and test cases. For details
please see individual patches. Thanks!
====================
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents 36153532 832c6f2c
...@@ -51,6 +51,9 @@ struct bpf_reg_state { ...@@ -51,6 +51,9 @@ struct bpf_reg_state {
* PTR_TO_MAP_VALUE_OR_NULL * PTR_TO_MAP_VALUE_OR_NULL
*/ */
struct bpf_map *map_ptr; struct bpf_map *map_ptr;
/* Max size from any of the above. */
unsigned long raw;
}; };
/* Fixed part of pointer offset, pointer types only */ /* Fixed part of pointer offset, pointer types only */
s32 off; s32 off;
......
...@@ -2852,10 +2852,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn ...@@ -2852,10 +2852,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
regs[BPF_REG_0].type = NOT_INIT; regs[BPF_REG_0].type = NOT_INIT;
} else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL || } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL ||
fn->ret_type == RET_PTR_TO_MAP_VALUE) { fn->ret_type == RET_PTR_TO_MAP_VALUE) {
if (fn->ret_type == RET_PTR_TO_MAP_VALUE)
regs[BPF_REG_0].type = PTR_TO_MAP_VALUE;
else
regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
/* There is no offset yet applied, variable or fixed */ /* There is no offset yet applied, variable or fixed */
mark_reg_known_zero(env, regs, BPF_REG_0); mark_reg_known_zero(env, regs, BPF_REG_0);
/* remember map_ptr, so that check_map_access() /* remember map_ptr, so that check_map_access()
...@@ -2868,7 +2864,12 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn ...@@ -2868,7 +2864,12 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
return -EINVAL; return -EINVAL;
} }
regs[BPF_REG_0].map_ptr = meta.map_ptr; regs[BPF_REG_0].map_ptr = meta.map_ptr;
regs[BPF_REG_0].id = ++env->id_gen; if (fn->ret_type == RET_PTR_TO_MAP_VALUE) {
regs[BPF_REG_0].type = PTR_TO_MAP_VALUE;
} else {
regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
regs[BPF_REG_0].id = ++env->id_gen;
}
} else if (fn->ret_type == RET_PTR_TO_SOCKET_OR_NULL) { } else if (fn->ret_type == RET_PTR_TO_SOCKET_OR_NULL) {
int id = acquire_reference_state(env, insn_idx); int id = acquire_reference_state(env, insn_idx);
if (id < 0) if (id < 0)
...@@ -3046,7 +3047,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, ...@@ -3046,7 +3047,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
dst_reg->umax_value = umax_ptr; dst_reg->umax_value = umax_ptr;
dst_reg->var_off = ptr_reg->var_off; dst_reg->var_off = ptr_reg->var_off;
dst_reg->off = ptr_reg->off + smin_val; dst_reg->off = ptr_reg->off + smin_val;
dst_reg->range = ptr_reg->range; dst_reg->raw = ptr_reg->raw;
break; break;
} }
/* A new variable offset is created. Note that off_reg->off /* A new variable offset is created. Note that off_reg->off
...@@ -3076,10 +3077,11 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, ...@@ -3076,10 +3077,11 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
} }
dst_reg->var_off = tnum_add(ptr_reg->var_off, off_reg->var_off); dst_reg->var_off = tnum_add(ptr_reg->var_off, off_reg->var_off);
dst_reg->off = ptr_reg->off; dst_reg->off = ptr_reg->off;
dst_reg->raw = ptr_reg->raw;
if (reg_is_pkt_pointer(ptr_reg)) { if (reg_is_pkt_pointer(ptr_reg)) {
dst_reg->id = ++env->id_gen; dst_reg->id = ++env->id_gen;
/* something was added to pkt_ptr, set range to zero */ /* something was added to pkt_ptr, set range to zero */
dst_reg->range = 0; dst_reg->raw = 0;
} }
break; break;
case BPF_SUB: case BPF_SUB:
...@@ -3108,7 +3110,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, ...@@ -3108,7 +3110,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
dst_reg->var_off = ptr_reg->var_off; dst_reg->var_off = ptr_reg->var_off;
dst_reg->id = ptr_reg->id; dst_reg->id = ptr_reg->id;
dst_reg->off = ptr_reg->off - smin_val; dst_reg->off = ptr_reg->off - smin_val;
dst_reg->range = ptr_reg->range; dst_reg->raw = ptr_reg->raw;
break; break;
} }
/* A new variable offset is created. If the subtrahend is known /* A new variable offset is created. If the subtrahend is known
...@@ -3134,11 +3136,12 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, ...@@ -3134,11 +3136,12 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
} }
dst_reg->var_off = tnum_sub(ptr_reg->var_off, off_reg->var_off); dst_reg->var_off = tnum_sub(ptr_reg->var_off, off_reg->var_off);
dst_reg->off = ptr_reg->off; dst_reg->off = ptr_reg->off;
dst_reg->raw = ptr_reg->raw;
if (reg_is_pkt_pointer(ptr_reg)) { if (reg_is_pkt_pointer(ptr_reg)) {
dst_reg->id = ++env->id_gen; dst_reg->id = ++env->id_gen;
/* something was added to pkt_ptr, set range to zero */ /* something was added to pkt_ptr, set range to zero */
if (smin_val < 0) if (smin_val < 0)
dst_reg->range = 0; dst_reg->raw = 0;
} }
break; break;
case BPF_AND: case BPF_AND:
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment