aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/verifier.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-05-02 22:14:21 -0400
committerDavid S. Miller <davem@davemloft.net>2019-05-02 22:14:21 -0400
commitff24e4980a68d83090a02fda081741a410fe8eef (patch)
tree4d874dfcaf2bb8c3abc2446af9447a983402c0ae /kernel/bpf/verifier.c
parent26f146ed971c0e4a264ce525d7a66a71ef73690d (diff)
parentea9866793d1e925b4d320eaea409263b2a568f38 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Three trivial overlapping conflicts. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf/verifier.c')
-rw-r--r--kernel/bpf/verifier.c76
1 files changed, 46 insertions, 30 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 271717246af3..7b05e8938d5c 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -4349,15 +4349,35 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
4349 return 0; 4349 return 0;
4350} 4350}
4351 4351
4352static void __find_good_pkt_pointers(struct bpf_func_state *state,
4353 struct bpf_reg_state *dst_reg,
4354 enum bpf_reg_type type, u16 new_range)
4355{
4356 struct bpf_reg_state *reg;
4357 int i;
4358
4359 for (i = 0; i < MAX_BPF_REG; i++) {
4360 reg = &state->regs[i];
4361 if (reg->type == type && reg->id == dst_reg->id)
4362 /* keep the maximum range already checked */
4363 reg->range = max(reg->range, new_range);
4364 }
4365
4366 bpf_for_each_spilled_reg(i, state, reg) {
4367 if (!reg)
4368 continue;
4369 if (reg->type == type && reg->id == dst_reg->id)
4370 reg->range = max(reg->range, new_range);
4371 }
4372}
4373
4352static void find_good_pkt_pointers(struct bpf_verifier_state *vstate, 4374static void find_good_pkt_pointers(struct bpf_verifier_state *vstate,
4353 struct bpf_reg_state *dst_reg, 4375 struct bpf_reg_state *dst_reg,
4354 enum bpf_reg_type type, 4376 enum bpf_reg_type type,
4355 bool range_right_open) 4377 bool range_right_open)
4356{ 4378{
4357 struct bpf_func_state *state = vstate->frame[vstate->curframe];
4358 struct bpf_reg_state *regs = state->regs, *reg;
4359 u16 new_range; 4379 u16 new_range;
4360 int i, j; 4380 int i;
4361 4381
4362 if (dst_reg->off < 0 || 4382 if (dst_reg->off < 0 ||
4363 (dst_reg->off == 0 && range_right_open)) 4383 (dst_reg->off == 0 && range_right_open))
@@ -4422,20 +4442,9 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *vstate,
4422 * the range won't allow anything. 4442 * the range won't allow anything.
4423 * dst_reg->off is known < MAX_PACKET_OFF, therefore it fits in a u16. 4443 * dst_reg->off is known < MAX_PACKET_OFF, therefore it fits in a u16.
4424 */ 4444 */
4425 for (i = 0; i < MAX_BPF_REG; i++) 4445 for (i = 0; i <= vstate->curframe; i++)
4426 if (regs[i].type == type && regs[i].id == dst_reg->id) 4446 __find_good_pkt_pointers(vstate->frame[i], dst_reg, type,
4427 /* keep the maximum range already checked */ 4447 new_range);
4428 regs[i].range = max(regs[i].range, new_range);
4429
4430 for (j = 0; j <= vstate->curframe; j++) {
4431 state = vstate->frame[j];
4432 bpf_for_each_spilled_reg(i, state, reg) {
4433 if (!reg)
4434 continue;
4435 if (reg->type == type && reg->id == dst_reg->id)
4436 reg->range = max(reg->range, new_range);
4437 }
4438 }
4439} 4448}
4440 4449
4441/* compute branch direction of the expression "if (reg opcode val) goto target;" 4450/* compute branch direction of the expression "if (reg opcode val) goto target;"
@@ -4909,6 +4918,22 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state,
4909 } 4918 }
4910} 4919}
4911 4920
4921static void __mark_ptr_or_null_regs(struct bpf_func_state *state, u32 id,
4922 bool is_null)
4923{
4924 struct bpf_reg_state *reg;
4925 int i;
4926
4927 for (i = 0; i < MAX_BPF_REG; i++)
4928 mark_ptr_or_null_reg(state, &state->regs[i], id, is_null);
4929
4930 bpf_for_each_spilled_reg(i, state, reg) {
4931 if (!reg)
4932 continue;
4933 mark_ptr_or_null_reg(state, reg, id, is_null);
4934 }
4935}
4936
4912/* The logic is similar to find_good_pkt_pointers(), both could eventually 4937/* The logic is similar to find_good_pkt_pointers(), both could eventually
4913 * be folded together at some point. 4938 * be folded together at some point.
4914 */ 4939 */
@@ -4916,10 +4941,10 @@ static void mark_ptr_or_null_regs(struct bpf_verifier_state *vstate, u32 regno,
4916 bool is_null) 4941 bool is_null)
4917{ 4942{
4918 struct bpf_func_state *state = vstate->frame[vstate->curframe]; 4943 struct bpf_func_state *state = vstate->frame[vstate->curframe];
4919 struct bpf_reg_state *reg, *regs = state->regs; 4944 struct bpf_reg_state *regs = state->regs;
4920 u32 ref_obj_id = regs[regno].ref_obj_id; 4945 u32 ref_obj_id = regs[regno].ref_obj_id;
4921 u32 id = regs[regno].id; 4946 u32 id = regs[regno].id;
4922 int i, j; 4947 int i;
4923 4948
4924 if (ref_obj_id && ref_obj_id == id && is_null) 4949 if (ref_obj_id && ref_obj_id == id && is_null)
4925 /* regs[regno] is in the " == NULL" branch. 4950 /* regs[regno] is in the " == NULL" branch.
@@ -4928,17 +4953,8 @@ static void mark_ptr_or_null_regs(struct bpf_verifier_state *vstate, u32 regno,
4928 */ 4953 */
4929 WARN_ON_ONCE(release_reference_state(state, id)); 4954 WARN_ON_ONCE(release_reference_state(state, id));
4930 4955
4931 for (i = 0; i < MAX_BPF_REG; i++) 4956 for (i = 0; i <= vstate->curframe; i++)
4932 mark_ptr_or_null_reg(state, &regs[i], id, is_null); 4957 __mark_ptr_or_null_regs(vstate->frame[i], id, is_null);
4933
4934 for (j = 0; j <= vstate->curframe; j++) {
4935 state = vstate->frame[j];
4936 bpf_for_each_spilled_reg(i, state, reg) {
4937 if (!reg)
4938 continue;
4939 mark_ptr_or_null_reg(state, reg, id, is_null);
4940 }
4941 }
4942} 4958}
4943 4959
4944static bool try_match_pkt_pointers(const struct bpf_insn *insn, 4960static bool try_match_pkt_pointers(const struct bpf_insn *insn,