aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@fb.com>2016-12-07 13:57:59 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-22 07:43:35 -0400
commitb7f5aa1ca0bedbd109be7563f6a94c9a37714537 (patch)
treede5205f1e514f09fa5b293ab5a90ec3a76dacbde
parent1411707acb85c514c603f692327c98db48127900 (diff)
bpf: fix state equivalence
[ Upstream commit d2a4dd37f6b41fbcad76efbf63124eb3126c66fe ] Commmits 57a09bf0a416 ("bpf: Detect identical PTR_TO_MAP_VALUE_OR_NULL registers") and 484611357c19 ("bpf: allow access into map value arrays") by themselves are correct, but in combination they make state equivalence ignore 'id' field of the register state which can lead to accepting invalid program. Fixes: 57a09bf0a416 ("bpf: Detect identical PTR_TO_MAP_VALUE_OR_NULL registers") Fixes: 484611357c19 ("bpf: allow access into map value arrays") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--include/linux/bpf_verifier.h14
-rw-r--r--kernel/bpf/verifier.c2
2 files changed, 8 insertions, 8 deletions
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 7453c1281531..a13b031dc6b8 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -18,13 +18,6 @@
18 18
19struct bpf_reg_state { 19struct bpf_reg_state {
20 enum bpf_reg_type type; 20 enum bpf_reg_type type;
21 /*
22 * Used to determine if any memory access using this register will
23 * result in a bad access.
24 */
25 s64 min_value;
26 u64 max_value;
27 u32 id;
28 union { 21 union {
29 /* valid when type == CONST_IMM | PTR_TO_STACK | UNKNOWN_VALUE */ 22 /* valid when type == CONST_IMM | PTR_TO_STACK | UNKNOWN_VALUE */
30 s64 imm; 23 s64 imm;
@@ -40,6 +33,13 @@ struct bpf_reg_state {
40 */ 33 */
41 struct bpf_map *map_ptr; 34 struct bpf_map *map_ptr;
42 }; 35 };
36 u32 id;
37 /* Used to determine if any memory access using this register will
38 * result in a bad access. These two fields must be last.
39 * See states_equal()
40 */
41 s64 min_value;
42 u64 max_value;
43}; 43};
44 44
45enum bpf_stack_slot_type { 45enum bpf_stack_slot_type {
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index c428c9f85186..6036d1e8c2a9 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2498,7 +2498,7 @@ static bool states_equal(struct bpf_verifier_env *env,
2498 * we didn't do a variable access into a map then we are a-ok. 2498 * we didn't do a variable access into a map then we are a-ok.
2499 */ 2499 */
2500 if (!varlen_map_access && 2500 if (!varlen_map_access &&
2501 rold->type == rcur->type && rold->imm == rcur->imm) 2501 memcmp(rold, rcur, offsetofend(struct bpf_reg_state, id)) == 0)
2502 continue; 2502 continue;
2503 2503
2504 /* If we didn't map access then again we don't care about the 2504 /* If we didn't map access then again we don't care about the