bpf, x64: fix memleak when not converging after image
[linux-2.6-microblaze.git] / arch / x86 / net / bpf_jit_comp.c
index b725154..9ae7b93 100644 (file)
@@ -1027,7 +1027,17 @@ emit_cond_jmp:           /* convert BPF opcode to x86 */
                        break;
 
                case BPF_JMP | BPF_JA:
-                       jmp_offset = addrs[i + insn->off] - addrs[i];
+                       if (insn->off == -1)
+                               /* -1 jmp instructions will always jump
+                                * backwards two bytes. Explicitly handling
+                                * this case avoids wasting too many passes
+                                * when there are long sequences of replaced
+                                * dead code.
+                                */
+                               jmp_offset = -2;
+                       else
+                               jmp_offset = addrs[i + insn->off] - addrs[i];
+
                        if (!jmp_offset)
                                /* optimize out nop jumps */
                                break;
@@ -1226,6 +1236,7 @@ skip_init_addrs:
        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);
@@ -1236,8 +1247,7 @@ skip_init_addrs:
                        if (proglen != oldproglen) {
                                pr_err("bpf_jit: proglen=%d != oldproglen=%d\n",
                                       proglen, oldproglen);
-                               prog = orig_prog;
-                               goto out_addrs;
+                               goto out_image;
                        }
                        break;
                }