@@ -330,8 +330,7 @@ static int emit_jump(u8 **pprog, void *func, void *ip)
330330}
331331
332332static int __bpf_arch_text_poke (void * ip , enum bpf_text_poke_type t ,
333- void * old_addr , void * new_addr ,
334- const bool text_live )
333+ void * old_addr , void * new_addr )
335334{
336335 const u8 * nop_insn = x86_nops [5 ];
337336 u8 old_insn [X86_PATCH_SIZE ];
@@ -365,10 +364,7 @@ static int __bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
365364 goto out ;
366365 ret = 1 ;
367366 if (memcmp (ip , new_insn , X86_PATCH_SIZE )) {
368- if (text_live )
369- text_poke_bp (ip , new_insn , X86_PATCH_SIZE , NULL );
370- else
371- memcpy (ip , new_insn , X86_PATCH_SIZE );
367+ text_poke_bp (ip , new_insn , X86_PATCH_SIZE , NULL );
372368 ret = 0 ;
373369 }
374370out :
@@ -384,7 +380,7 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
384380 /* BPF poking in modules is not supported */
385381 return - EINVAL ;
386382
387- return __bpf_arch_text_poke (ip , t , old_addr , new_addr , true );
383+ return __bpf_arch_text_poke (ip , t , old_addr , new_addr );
388384}
389385
390386#define EMIT_LFENCE () EMIT3(0x0F, 0xAE, 0xE8)
@@ -558,24 +554,15 @@ static void bpf_tail_call_direct_fixup(struct bpf_prog *prog)
558554 mutex_lock (& array -> aux -> poke_mutex );
559555 target = array -> ptrs [poke -> tail_call .key ];
560556 if (target ) {
561- /* Plain memcpy is used when image is not live yet
562- * and still not locked as read-only. Once poke
563- * location is active (poke->tailcall_target_stable),
564- * any parallel bpf_arch_text_poke() might occur
565- * still on the read-write image until we finally
566- * locked it as read-only. Both modifications on
567- * the given image are under text_mutex to avoid
568- * interference.
569- */
570557 ret = __bpf_arch_text_poke (poke -> tailcall_target ,
571558 BPF_MOD_JUMP , NULL ,
572559 (u8 * )target -> bpf_func +
573- poke -> adj_off , false );
560+ poke -> adj_off );
574561 BUG_ON (ret < 0 );
575562 ret = __bpf_arch_text_poke (poke -> tailcall_bypass ,
576563 BPF_MOD_JUMP ,
577564 (u8 * )poke -> tailcall_target +
578- X86_PATCH_SIZE , NULL , false );
565+ X86_PATCH_SIZE , NULL );
579566 BUG_ON (ret < 0 );
580567 }
581568 WRITE_ONCE (poke -> tailcall_target_stable , true);
@@ -866,7 +853,7 @@ static void emit_nops(u8 **pprog, int len)
866853
867854#define INSN_SZ_DIFF (((addrs[i] - addrs[i - 1]) - (prog - temp)))
868855
869- static int do_jit (struct bpf_prog * bpf_prog , int * addrs , u8 * image ,
856+ static int do_jit (struct bpf_prog * bpf_prog , int * addrs , u8 * image , u8 * rw_image ,
870857 int oldproglen , struct jit_context * ctx , bool jmp_padding )
871858{
872859 bool tail_call_reachable = bpf_prog -> aux -> tail_call_reachable ;
@@ -893,8 +880,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
893880 push_callee_regs (& prog , callee_regs_used );
894881
895882 ilen = prog - temp ;
896- if (image )
897- memcpy (image + proglen , temp , ilen );
883+ if (rw_image )
884+ memcpy (rw_image + proglen , temp , ilen );
898885 proglen += ilen ;
899886 addrs [0 ] = proglen ;
900887 prog = temp ;
@@ -1323,6 +1310,9 @@ st: if (is_imm8(insn->off))
13231310 pr_err ("extable->insn doesn't fit into 32-bit\n" );
13241311 return - EFAULT ;
13251312 }
1313+ /* switch ex to rw buffer for writes */
1314+ ex = (void * )rw_image + ((void * )ex - (void * )image );
1315+
13261316 ex -> insn = delta ;
13271317
13281318 ex -> data = EX_TYPE_BPF ;
@@ -1705,7 +1695,7 @@ st: if (is_imm8(insn->off))
17051695 pr_err ("bpf_jit: fatal error\n" );
17061696 return - EFAULT ;
17071697 }
1708- memcpy (image + proglen , temp , ilen );
1698+ memcpy (rw_image + proglen , temp , ilen );
17091699 }
17101700 proglen += ilen ;
17111701 addrs [i ] = proglen ;
@@ -2246,6 +2236,7 @@ int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
22462236}
22472237
22482238struct x64_jit_data {
2239+ struct bpf_binary_header * rw_header ;
22492240 struct bpf_binary_header * header ;
22502241 int * addrs ;
22512242 u8 * image ;
@@ -2258,6 +2249,7 @@ struct x64_jit_data {
22582249
22592250struct bpf_prog * bpf_int_jit_compile (struct bpf_prog * prog )
22602251{
2252+ struct bpf_binary_header * rw_header = NULL ;
22612253 struct bpf_binary_header * header = NULL ;
22622254 struct bpf_prog * tmp , * orig_prog = prog ;
22632255 struct x64_jit_data * jit_data ;
@@ -2266,6 +2258,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
22662258 bool tmp_blinded = false;
22672259 bool extra_pass = false;
22682260 bool padding = false;
2261+ u8 * rw_image = NULL ;
22692262 u8 * image = NULL ;
22702263 int * addrs ;
22712264 int pass ;
@@ -2301,6 +2294,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
23012294 oldproglen = jit_data -> proglen ;
23022295 image = jit_data -> image ;
23032296 header = jit_data -> header ;
2297+ rw_header = jit_data -> rw_header ;
2298+ rw_image = (void * )rw_header + ((void * )image - (void * )header );
23042299 extra_pass = true;
23052300 padding = true;
23062301 goto skip_init_addrs ;
@@ -2331,12 +2326,12 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
23312326 for (pass = 0 ; pass < MAX_PASSES || image ; pass ++ ) {
23322327 if (!padding && pass >= PADDING_PASSES )
23332328 padding = true;
2334- proglen = do_jit (prog , addrs , image , oldproglen , & ctx , padding );
2329+ proglen = do_jit (prog , addrs , image , rw_image , oldproglen , & ctx , padding );
23352330 if (proglen <= 0 ) {
23362331out_image :
23372332 image = NULL ;
23382333 if (header )
2339- bpf_jit_binary_free (header );
2334+ bpf_jit_binary_pack_free (header , rw_header );
23402335 prog = orig_prog ;
23412336 goto out_addrs ;
23422337 }
@@ -2360,8 +2355,9 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
23602355 sizeof (struct exception_table_entry );
23612356
23622357 /* allocate module memory for x86 insns and extable */
2363- header = bpf_jit_binary_alloc (roundup (proglen , align ) + extable_size ,
2364- & image , align , jit_fill_hole );
2358+ header = bpf_jit_binary_pack_alloc (roundup (proglen , align ) + extable_size ,
2359+ & image , align , & rw_header , & rw_image ,
2360+ jit_fill_hole );
23652361 if (!header ) {
23662362 prog = orig_prog ;
23672363 goto out_addrs ;
@@ -2377,14 +2373,22 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
23772373
23782374 if (image ) {
23792375 if (!prog -> is_func || extra_pass ) {
2376+ /*
2377+ * bpf_jit_binary_pack_finalize fails in two scenarios:
2378+ * 1) header is not pointing to proper module memory;
2379+ * 2) the arch doesn't support bpf_arch_text_copy().
2380+ *
2381+ * Both cases are serious bugs that we should not continue.
2382+ */
2383+ BUG_ON (bpf_jit_binary_pack_finalize (prog , header , rw_header ));
23802384 bpf_tail_call_direct_fixup (prog );
2381- bpf_jit_binary_lock_ro (header );
23822385 } else {
23832386 jit_data -> addrs = addrs ;
23842387 jit_data -> ctx = ctx ;
23852388 jit_data -> proglen = proglen ;
23862389 jit_data -> image = image ;
23872390 jit_data -> header = header ;
2391+ jit_data -> rw_header = rw_header ;
23882392 }
23892393 prog -> bpf_func = (void * )image ;
23902394 prog -> jited = 1 ;
0 commit comments