bpf: don't mark FP reg as uninit
authorAlexei Starovoitov <ast@fb.com>
Fri, 1 Dec 2017 05:31:37 +0000 (21:31 -0800)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 1 Dec 2017 10:25:10 +0000 (11:25 +0100)
when verifier hits an internal bug don't mark register R10==FP as uninit,
since it's read only register and it's not technically correct to let
verifier run further, since it may assume that R10 has valid auxiliary state.

While developing subsequent patches this issue was discovered,
though the code eventually changed that aux reg state doesn't have
pointers any more it is still safer to avoid clearing readonly register.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
kernel/bpf/verifier.c

index f7229390c27985b8a93138f22491c231c2ac6e98..14ad7c6e806ab3650edd1860f587d9c2af1af8ab 100644 (file)
@@ -584,8 +584,8 @@ static void mark_reg_unknown(struct bpf_verifier_env *env,
 {
        if (WARN_ON(regno >= MAX_BPF_REG)) {
                verbose(env, "mark_reg_unknown(regs, %u)\n", regno);
-               /* Something bad happened, let's kill all regs */
-               for (regno = 0; regno < MAX_BPF_REG; regno++)
+               /* Something bad happened, let's kill all regs except FP */
+               for (regno = 0; regno < BPF_REG_FP; regno++)
                        __mark_reg_not_init(regs + regno);
                return;
        }
@@ -603,8 +603,8 @@ static void mark_reg_not_init(struct bpf_verifier_env *env,
 {
        if (WARN_ON(regno >= MAX_BPF_REG)) {
                verbose(env, "mark_reg_not_init(regs, %u)\n", regno);
-               /* Something bad happened, let's kill all regs */
-               for (regno = 0; regno < MAX_BPF_REG; regno++)
+               /* Something bad happened, let's kill all regs except FP */
+               for (regno = 0; regno < BPF_REG_FP; regno++)
                        __mark_reg_not_init(regs + regno);
                return;
        }