Skip to content

Commit 60b58af

Browse files
4astborkmann
authored andcommitted
bpf: fix net.core.bpf_jit_enable race
global bpf_jit_enable variable is tested multiple times in JITs, blinding and verifier core. The malicious root can try to toggle it while loading the programs. This race condition was accounted for and there should be no issues, but it's safer to avoid this race condition. Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Daniel Borkmann <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent 1ea47e0 commit 60b58af

File tree

10 files changed

+13
-11
lines changed

10 files changed

+13
-11
lines changed

arch/arm/net/bpf_jit_32.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1824,7 +1824,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
18241824
/* If BPF JIT was not enabled then we must fall back to
18251825
* the interpreter.
18261826
*/
1827-
if (!bpf_jit_enable)
1827+
if (!prog->jit_requested)
18281828
return orig_prog;
18291829

18301830
/* If constant blinding was enabled and we failed during blinding

arch/arm64/net/bpf_jit_comp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
844844
int image_size;
845845
u8 *image_ptr;
846846

847-
if (!bpf_jit_enable)
847+
if (!prog->jit_requested)
848848
return orig_prog;
849849

850850
tmp = bpf_jit_blind_constants(prog);

arch/mips/net/ebpf_jit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1869,7 +1869,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
18691869
unsigned int image_size;
18701870
u8 *image_ptr;
18711871

1872-
if (!bpf_jit_enable || !cpu_has_mips64r2)
1872+
if (!prog->jit_requested || !cpu_has_mips64r2)
18731873
return prog;
18741874

18751875
tmp = bpf_jit_blind_constants(prog);

arch/powerpc/net/bpf_jit_comp64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -993,7 +993,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
993993
struct bpf_prog *tmp_fp;
994994
bool bpf_blinded = false;
995995

996-
if (!bpf_jit_enable)
996+
if (!fp->jit_requested)
997997
return org_fp;
998998

999999
tmp_fp = bpf_jit_blind_constants(org_fp);

arch/s390/net/bpf_jit_comp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1300,7 +1300,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
13001300
struct bpf_jit jit;
13011301
int pass;
13021302

1303-
if (!bpf_jit_enable)
1303+
if (!fp->jit_requested)
13041304
return orig_fp;
13051305

13061306
tmp = bpf_jit_blind_constants(fp);

arch/sparc/net/bpf_jit_comp_64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1517,7 +1517,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
15171517
u8 *image_ptr;
15181518
int pass;
15191519

1520-
if (!bpf_jit_enable)
1520+
if (!prog->jit_requested)
15211521
return orig_prog;
15221522

15231523
tmp = bpf_jit_blind_constants(prog);

arch/x86/net/bpf_jit_comp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
11211121
int pass;
11221122
int i;
11231123

1124-
if (!bpf_jit_enable)
1124+
if (!prog->jit_requested)
11251125
return orig_prog;
11261126

11271127
tmp = bpf_jit_blind_constants(prog);

include/linux/filter.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,7 @@ struct bpf_binary_header {
458458
struct bpf_prog {
459459
u16 pages; /* Number of allocated pages */
460460
u16 jited:1, /* Is our filter JIT'ed? */
461+
jit_requested:1,/* archs need to JIT the prog */
461462
locked:1, /* Program image locked? */
462463
gpl_compatible:1, /* Is filter GPL compatible? */
463464
cb_access:1, /* Is control block accessed? */
@@ -804,15 +805,15 @@ static inline bool bpf_prog_ebpf_jited(const struct bpf_prog *fp)
804805
return fp->jited && bpf_jit_is_ebpf();
805806
}
806807

807-
static inline bool bpf_jit_blinding_enabled(void)
808+
static inline bool bpf_jit_blinding_enabled(struct bpf_prog *prog)
808809
{
809810
/* These are the prerequisites, should someone ever have the
810811
* idea to call blinding outside of them, we make sure to
811812
* bail out.
812813
*/
813814
if (!bpf_jit_is_ebpf())
814815
return false;
815-
if (!bpf_jit_enable)
816+
if (!prog->jit_requested)
816817
return false;
817818
if (!bpf_jit_harden)
818819
return false;

kernel/bpf/core.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags)
9494
fp->pages = size / PAGE_SIZE;
9595
fp->aux = aux;
9696
fp->aux->prog = fp;
97+
fp->jit_requested = ebpf_jit_enabled();
9798

9899
INIT_LIST_HEAD_RCU(&fp->aux->ksym_lnode);
99100

@@ -721,7 +722,7 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *prog)
721722
struct bpf_insn *insn;
722723
int i, rewritten;
723724

724-
if (!bpf_jit_blinding_enabled())
725+
if (!bpf_jit_blinding_enabled(prog))
725726
return prog;
726727

727728
clone = bpf_prog_clone_create(prog, GFP_USER);

kernel/bpf/verifier.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5080,7 +5080,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
50805080
/* BPF_EMIT_CALL() assumptions in some of the map_gen_lookup
50815081
* handlers are currently limited to 64 bit only.
50825082
*/
5083-
if (ebpf_jit_enabled() && BITS_PER_LONG == 64 &&
5083+
if (prog->jit_requested && BITS_PER_LONG == 64 &&
50845084
insn->imm == BPF_FUNC_map_lookup_elem) {
50855085
map_ptr = env->insn_aux_data[i + delta].map_ptr;
50865086
if (map_ptr == BPF_MAP_PTR_POISON ||

0 commit comments

Comments
 (0)