Home Home > GIT Browse
diff options
authorBen Hutchings <ben@decadent.org.uk>2017-12-23 02:26:17 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-12-29 17:43:00 +0100
commit37435f7e80ef9adc32a69013c18f135e3f434244 (patch)
parent69cf72b2879167364d2a97211fbb26ca0e374bcf (diff)
bpf/verifier: Fix states_equal() comparison of pointer and UNKNOWN
An UNKNOWN_VALUE is not supposed to be derived from a pointer, unless pointer leaks are allowed. Therefore, states_equal() must not treat a state with a pointer in a register as "equal" to a state with an UNKNOWN_VALUE in that register. This was fixed differently upstream, but the code around here was largely rewritten in 4.14 by commit f1174f77b50c "bpf/verifier: rework value tracking". The bug can be detected by the bpf/verifier sub-test "pointer/scalar confusion in state equality check (way 1)". Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Cc: Edward Cree <ecree@solarflare.com> Cc: Jann Horn <jannh@google.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Daniel Borkmann <daniel@iogearbox.net>
1 files changed, 3 insertions, 2 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 8b1ebe4c6aba..d7eeebfafe8d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2722,11 +2722,12 @@ static bool states_equal(struct bpf_verifier_env *env,
/* If we didn't map access then again we don't care about the
* mismatched range values and it's ok if our old type was
- * UNKNOWN and we didn't go to a NOT_INIT'ed reg.
+ * UNKNOWN and we didn't go to a NOT_INIT'ed or pointer reg.
if (rold->type == NOT_INIT ||
(!varlen_map_access && rold->type == UNKNOWN_VALUE &&
- rcur->type != NOT_INIT))
+ rcur->type != NOT_INIT &&
+ !__is_pointer_value(env->allow_ptr_leaks, rcur)))
/* Don't care about the reg->id in this case. */