bpf: get rid of pure_initcall dependency to enable jits
authorDaniel Borkmann <daniel@iogearbox.net>
Fri, 16 Aug 2019 22:04:32 +0000 (23:04 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 25 Aug 2019 08:50:02 +0000 (10:50 +0200)
commit fa9dd599b4dae841924b022768354cfde9affecb upstream.

Having a pure_initcall() callback just to permanently enable BPF
JITs under CONFIG_BPF_JIT_ALWAYS_ON is unnecessary and could leave
a small race window in future where JIT is still disabled on boot.
Since we know about the setting at compilation time anyway, just
initialize it properly there. Also consolidate all the individual
bpf_jit_enable variables into a single one and move them under one
location. Moreover, don't allow for setting unspecified garbage
values on them.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
[bwh: Backported to 4.14 as dependency of commit 2e4a30983b0f
 "bpf: restrict access to core bpf sysctls":
 - Adjust context]
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
13 files changed:
arch/arm/net/bpf_jit_32.c
arch/arm64/net/bpf_jit_comp.c
arch/mips/net/bpf_jit.c
arch/mips/net/ebpf_jit.c
arch/powerpc/net/bpf_jit_comp.c
arch/powerpc/net/bpf_jit_comp64.c
arch/s390/net/bpf_jit_comp.c
arch/sparc/net/bpf_jit_comp_32.c
arch/sparc/net/bpf_jit_comp_64.c
arch/x86/net/bpf_jit_comp.c
kernel/bpf/core.c
net/core/sysctl_net_core.c
net/socket.c

index dafeb5f81353efaed3d7b9ef4529d1e33c040ee9..b18fb70c5dcf9b1b2cc6338ee8f79507e43376f7 100644 (file)
@@ -25,8 +25,6 @@
 
 #include "bpf_jit_32.h"
 
-int bpf_jit_enable __read_mostly;
-
 /*
  * eBPF prog stack layout:
  *
index b742171bfef74cec70ed1c56017dd668a5aed82a..1bbb457c293f91d88ae3c149caee0b7f80ed8767 100644 (file)
@@ -31,8 +31,6 @@
 
 #include "bpf_jit.h"
 
-int bpf_jit_enable __read_mostly;
-
 #define TMP_REG_1 (MAX_BPF_JIT_REG + 0)
 #define TMP_REG_2 (MAX_BPF_JIT_REG + 1)
 #define TCALL_CNT (MAX_BPF_JIT_REG + 2)
index 44b925005dd37c78d8c85a814bef8ed69c927522..4d8cb9bb8365d07660d33c8049c045502fd4e1c6 100644 (file)
@@ -1207,8 +1207,6 @@ jmp_cmp:
        return 0;
 }
 
-int bpf_jit_enable __read_mostly;
-
 void bpf_jit_compile(struct bpf_prog *fp)
 {
        struct jit_ctx ctx;
index 8004bfcfb033ac1792dd49b920551c54cacac6dd..42faa95ce66425b55b5632fb9e4fc5ff4c3221ac 100644 (file)
@@ -177,8 +177,6 @@ static u32 b_imm(unsigned int tgt, struct jit_ctx *ctx)
                (ctx->idx * 4) - 4;
 }
 
-int bpf_jit_enable __read_mostly;
-
 enum which_ebpf_reg {
        src_reg,
        src_reg_no_fp,
index f760494ecd66d6fd9eb33a478e0534bd4fc355cd..a9636d8cba153a1fb43469c1b8070b59ae4ba210 100644 (file)
@@ -18,8 +18,6 @@
 
 #include "bpf_jit32.h"
 
-int bpf_jit_enable __read_mostly;
-
 static inline void bpf_flush_icache(void *start, void *end)
 {
        smp_wmb();
index 70e8216a39f0ed9fb4ec3cd85519faef25f3fbad..28434040cfb617f3e582c521c9d095ff28573b5d 100644 (file)
@@ -21,8 +21,6 @@
 
 #include "bpf_jit64.h"
 
-int bpf_jit_enable __read_mostly;
-
 static void bpf_jit_fill_ill_insns(void *area, unsigned int size)
 {
        memset32(area, BREAKPOINT_INSTRUCTION, size/4);
index 6b1474fa99ab3f98f68227fa97fc4d0768445ac3..bc9431aace05db3263ee447fd6652b94e107603a 100644 (file)
@@ -30,8 +30,6 @@
 #include <asm/set_memory.h>
 #include "bpf_jit.h"
 
-int bpf_jit_enable __read_mostly;
-
 struct bpf_jit {
        u32 seen;               /* Flags to remember seen eBPF instructions */
        u32 seen_reg[16];       /* Array to remember which registers are used */
index 09e318eb34eeae592f2eeafd6fdd7160c456494f..3bd8ca95e5210a5f7dd5c1700a90a650379de37a 100644 (file)
@@ -11,8 +11,6 @@
 
 #include "bpf_jit_32.h"
 
-int bpf_jit_enable __read_mostly;
-
 static inline bool is_simm13(unsigned int value)
 {
        return value + 0x1000 < 0x2000;
index ff5f9cb3039af1f91c8701915f08c051c21d0d81..adfb4581bd809d218410e2b3e12a56b644ac6ab2 100644 (file)
@@ -12,8 +12,6 @@
 
 #include "bpf_jit_64.h"
 
-int bpf_jit_enable __read_mostly;
-
 static inline bool is_simm13(unsigned int value)
 {
        return value + 0x1000 < 0x2000;
index a9deb2b0397de7e83fe7c44e5553b7ababbe2bb3..cdb386fa710134712bf01147bc60c94fe87bdd0b 100644 (file)
@@ -16,8 +16,6 @@
 #include <asm/nospec-branch.h>
 #include <linux/bpf.h>
 
-int bpf_jit_enable __read_mostly;
-
 /*
  * assembly code in arch/x86/net/bpf_jit.S
  */
index e46106c6ac393033eeb2d39660f20d5a37548b30..661fb837b16820270f1c7ac4654ce5c55ff7d342 100644 (file)
@@ -290,6 +290,11 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
 }
 
 #ifdef CONFIG_BPF_JIT
+/* All BPF JIT sysctl knobs here. */
+int bpf_jit_enable   __read_mostly = IS_BUILTIN(CONFIG_BPF_JIT_ALWAYS_ON);
+int bpf_jit_harden   __read_mostly;
+int bpf_jit_kallsyms __read_mostly;
+
 static __always_inline void
 bpf_get_prog_addr_region(const struct bpf_prog *prog,
                         unsigned long *symbol_start,
@@ -358,8 +363,6 @@ static DEFINE_SPINLOCK(bpf_lock);
 static LIST_HEAD(bpf_kallsyms);
 static struct latch_tree_root bpf_tree __cacheline_aligned;
 
-int bpf_jit_kallsyms __read_mostly;
-
 static void bpf_prog_ksym_node_add(struct bpf_prog_aux *aux)
 {
        WARN_ON_ONCE(!list_empty(&aux->ksym_lnode));
@@ -540,8 +543,6 @@ void __weak bpf_jit_free(struct bpf_prog *fp)
        bpf_prog_unlock_free(fp);
 }
 
-int bpf_jit_harden __read_mostly;
-
 static int bpf_jit_blind_insn(const struct bpf_insn *from,
                              const struct bpf_insn *aux,
                              struct bpf_insn *to_buff)
@@ -1327,9 +1328,13 @@ EVAL4(PROG_NAME_LIST, 416, 448, 480, 512)
 };
 
 #else
-static unsigned int __bpf_prog_ret0(const void *ctx,
-                                   const struct bpf_insn *insn)
+static unsigned int __bpf_prog_ret0_warn(const void *ctx,
+                                        const struct bpf_insn *insn)
 {
+       /* If this handler ever gets executed, then BPF_JIT_ALWAYS_ON
+        * is not working properly, so warn about it!
+        */
+       WARN_ON_ONCE(1);
        return 0;
 }
 #endif
@@ -1386,7 +1391,7 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)
 
        fp->bpf_func = interpreters[(round_up(stack_depth, 32) / 32) - 1];
 #else
-       fp->bpf_func = __bpf_prog_ret0;
+       fp->bpf_func = __bpf_prog_ret0_warn;
 #endif
 
        /* eBPF JITs can rewrite the program in case constant
index a47ad6cd41c0396558ee6666ae45e78f36d64bd5..6d39b4c01fc6d22b0e18973b82edf97ef0714c33 100644 (file)
@@ -25,6 +25,7 @@
 
 static int zero = 0;
 static int one = 1;
+static int two __maybe_unused = 2;
 static int min_sndbuf = SOCK_MIN_SNDBUF;
 static int min_rcvbuf = SOCK_MIN_RCVBUF;
 static int max_skb_frags = MAX_SKB_FRAGS;
@@ -325,13 +326,14 @@ static struct ctl_table net_core_table[] = {
                .data           = &bpf_jit_enable,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-#ifndef CONFIG_BPF_JIT_ALWAYS_ON
-               .proc_handler   = proc_dointvec
-#else
                .proc_handler   = proc_dointvec_minmax,
+# ifdef CONFIG_BPF_JIT_ALWAYS_ON
                .extra1         = &one,
                .extra2         = &one,
-#endif
+# else
+               .extra1         = &zero,
+               .extra2         = &two,
+# endif
        },
 # ifdef CONFIG_HAVE_EBPF_JIT
        {
@@ -339,14 +341,18 @@ static struct ctl_table net_core_table[] = {
                .data           = &bpf_jit_harden,
                .maxlen         = sizeof(int),
                .mode           = 0600,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &two,
        },
        {
                .procname       = "bpf_jit_kallsyms",
                .data           = &bpf_jit_kallsyms,
                .maxlen         = sizeof(int),
                .mode           = 0600,
-               .proc_handler   = proc_dointvec,
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &one,
        },
 # endif
 #endif
index 6d8f0c248c7eca3ea49cf8cf96a77ff1b7e77141..aab65277314d94ce0a3d1a162e1d86a674c99dcb 100644 (file)
@@ -2656,15 +2656,6 @@ out_fs:
 
 core_initcall(sock_init);      /* early initcall */
 
-static int __init jit_init(void)
-{
-#ifdef CONFIG_BPF_JIT_ALWAYS_ON
-       bpf_jit_enable = 1;
-#endif
-       return 0;
-}
-pure_initcall(jit_init);
-
 #ifdef CONFIG_PROC_FS
 void socket_seq_show(struct seq_file *seq)
 {