aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2016-11-29 12:27:09 -0500
committerDavid S. Miller <davem@davemloft.net>2016-11-30 14:50:52 -0500
commite2d2afe15ed452f91797a80dbc0a17838ba03ed4 (patch)
tree44cb85851f4f9aebe00a6405197e4766bed2cf83
parent0fcba2894c6b370ebf4b49099d20ff6333a430f7 (diff)
bpf: fix states equal logic for varlen access
If we have a branch that looks something like this int foo = map->value; if (condition) { foo += blah; } else { foo = bar; } map->array[foo] = baz; We will incorrectly assume that the !condition branch is equal to the condition branch as the register for foo will be UNKNOWN_VALUE in both cases. We need to adjust this logic to only do this if we didn't do a varlen access after we processed the !condition branch, otherwise we have different ranges and need to check the other branch as well. Fixes: 484611357c19 ("bpf: allow access into map value arrays") Reported-by: Jann Horn <jannh@google.com> Signed-off-by: Josef Bacik <jbacik@fb.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--kernel/bpf/verifier.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 6a936159c6e0..8199821f54cf 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2454,6 +2454,7 @@ static bool states_equal(struct bpf_verifier_env *env,
2454 struct bpf_verifier_state *old, 2454 struct bpf_verifier_state *old,
2455 struct bpf_verifier_state *cur) 2455 struct bpf_verifier_state *cur)
2456{ 2456{
2457 bool varlen_map_access = env->varlen_map_value_access;
2457 struct bpf_reg_state *rold, *rcur; 2458 struct bpf_reg_state *rold, *rcur;
2458 int i; 2459 int i;
2459 2460
@@ -2467,12 +2468,17 @@ static bool states_equal(struct bpf_verifier_env *env,
2467 /* If the ranges were not the same, but everything else was and 2468 /* If the ranges were not the same, but everything else was and
2468 * we didn't do a variable access into a map then we are a-ok. 2469 * we didn't do a variable access into a map then we are a-ok.
2469 */ 2470 */
2470 if (!env->varlen_map_value_access && 2471 if (!varlen_map_access &&
2471 rold->type == rcur->type && rold->imm == rcur->imm) 2472 rold->type == rcur->type && rold->imm == rcur->imm)
2472 continue; 2473 continue;
2473 2474
2475 /* If we didn't map access then again we don't care about the
2476 * mismatched range values and it's ok if our old type was
2477 * UNKNOWN and we didn't go to a NOT_INIT'ed reg.
2478 */
2474 if (rold->type == NOT_INIT || 2479 if (rold->type == NOT_INIT ||
2475 (rold->type == UNKNOWN_VALUE && rcur->type != NOT_INIT)) 2480 (!varlen_map_access && rold->type == UNKNOWN_VALUE &&
2481 rcur->type != NOT_INIT))
2476 continue; 2482 continue;
2477 2483
2478 if (rold->type == PTR_TO_PACKET && rcur->type == PTR_TO_PACKET && 2484 if (rold->type == PTR_TO_PACKET && rcur->type == PTR_TO_PACKET &&