]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
bpf, x64: fix memleak when not converging after image
authorDaniel Borkmann <daniel@iogearbox.net>
Wed, 2 May 2018 18:12:22 +0000 (20:12 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 2 May 2018 19:35:47 +0000 (12:35 -0700)
While reviewing x64 JIT code, I noticed that we leak the prior allocated
JIT image in the case where proglen != oldproglen during the JIT passes.
Prior to the commit e0ee9c12157d ("x86: bpf_jit: fix two bugs in eBPF JIT
compiler") we would just break out of the loop, and using the image as the
JITed prog since it could only shrink in size anyway. After e0ee9c12157d,
we would bail out to out_addrs label where we free addrs and jit_data but
not the image coming from bpf_jit_binary_alloc().

Fixes: e0ee9c12157d ("x86: bpf_jit: fix two bugs in eBPF JIT compiler")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
arch/x86/net/bpf_jit_comp.c

index abce27ceb411ae61b1af86ee52342ef4cd0ef37f..9ae7b9372348bfc1ae9eabeaf3d424054ce0cc87 100644 (file)
@@ -1236,6 +1236,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
        for (pass = 0; pass < 20 || image; pass++) {
                proglen = do_jit(prog, addrs, image, oldproglen, &ctx);
                if (proglen <= 0) {
+out_image:
                        image = NULL;
                        if (header)
                                bpf_jit_binary_free(header);
@@ -1246,8 +1247,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
                        if (proglen != oldproglen) {
                                pr_err("bpf_jit: proglen=%d != oldproglen=%d\n",
                                       proglen, oldproglen);
-                               prog = orig_prog;
-                               goto out_addrs;
+                               goto out_image;
                        }
                        break;
                }