diff options
author | David S. Miller <davem@davemloft.net> | 2019-05-02 22:14:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-05-02 22:14:21 -0400 |
commit | ff24e4980a68d83090a02fda081741a410fe8eef (patch) | |
tree | 4d874dfcaf2bb8c3abc2446af9447a983402c0ae /kernel/bpf/verifier.c | |
parent | 26f146ed971c0e4a264ce525d7a66a71ef73690d (diff) | |
parent | ea9866793d1e925b4d320eaea409263b2a568f38 (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.c | 76 |
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 | ||
4352 | static 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 | |||
4352 | static void find_good_pkt_pointers(struct bpf_verifier_state *vstate, | 4374 | static 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 | ||
4921 | static 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, ®s[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 | ||
4944 | static bool try_match_pkt_pointers(const struct bpf_insn *insn, | 4960 | static bool try_match_pkt_pointers(const struct bpf_insn *insn, |