3030#define TMP_REG_2 (MAX_BPF_JIT_REG + 1)
3131#define TCCNT_PTR (MAX_BPF_JIT_REG + 2)
3232#define TMP_REG_3 (MAX_BPF_JIT_REG + 3)
33+ #define PRIVATE_SP (MAX_BPF_JIT_REG + 4)
3334#define ARENA_VM_START (MAX_BPF_JIT_REG + 5)
3435
3536#define check_imm (bits , imm ) do { \
@@ -68,6 +69,8 @@ static const int bpf2a64[] = {
6869 [TCCNT_PTR ] = A64_R (26 ),
6970 /* temporary register for blinding constants */
7071 [BPF_REG_AX ] = A64_R (9 ),
72+ /* callee saved register for private stack pointer */
73+ [PRIVATE_SP ] = A64_R (27 ),
7174 /* callee saved register for kern_vm_start address */
7275 [ARENA_VM_START ] = A64_R (28 ),
7376};
@@ -86,6 +89,7 @@ struct jit_ctx {
8689 u64 user_vm_start ;
8790 u64 arena_vm_start ;
8891 bool fp_used ;
92+ bool priv_sp_used ;
8993 bool write ;
9094};
9195
@@ -98,6 +102,10 @@ struct bpf_plt {
98102#define PLT_TARGET_SIZE sizeof_field(struct bpf_plt, target)
99103#define PLT_TARGET_OFFSET offsetof(struct bpf_plt, target)
100104
105+ /* Memory size/value to protect private stack overflow/underflow */
106+ #define PRIV_STACK_GUARD_SZ 16
107+ #define PRIV_STACK_GUARD_VAL 0xEB9F12345678eb9fULL
108+
101109static inline void emit (const u32 insn , struct jit_ctx * ctx )
102110{
103111 if (ctx -> image != NULL && ctx -> write )
@@ -387,8 +395,11 @@ static void find_used_callee_regs(struct jit_ctx *ctx)
387395 if (reg_used & 8 )
388396 ctx -> used_callee_reg [i ++ ] = bpf2a64 [BPF_REG_9 ];
389397
390- if (reg_used & 16 )
398+ if (reg_used & 16 ) {
391399 ctx -> used_callee_reg [i ++ ] = bpf2a64 [BPF_REG_FP ];
400+ if (ctx -> priv_sp_used )
401+ ctx -> used_callee_reg [i ++ ] = bpf2a64 [PRIVATE_SP ];
402+ }
392403
393404 if (ctx -> arena_vm_start )
394405 ctx -> used_callee_reg [i ++ ] = bpf2a64 [ARENA_VM_START ];
@@ -461,6 +472,19 @@ static void pop_callee_regs(struct jit_ctx *ctx)
461472 }
462473}
463474
475+ static void emit_percpu_ptr (const u8 dst_reg , void __percpu * ptr ,
476+ struct jit_ctx * ctx )
477+ {
478+ const u8 tmp = bpf2a64 [TMP_REG_1 ];
479+
480+ emit_a64_mov_i64 (dst_reg , (__force const u64 )ptr , ctx );
481+ if (cpus_have_cap (ARM64_HAS_VIRT_HOST_EXTN ))
482+ emit (A64_MRS_TPIDR_EL2 (tmp ), ctx );
483+ else
484+ emit (A64_MRS_TPIDR_EL1 (tmp ), ctx );
485+ emit (A64_ADD (1 , dst_reg , dst_reg , tmp ), ctx );
486+ }
487+
464488#define BTI_INSNS (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) ? 1 : 0)
465489#define PAC_INSNS (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL) ? 1 : 0)
466490
@@ -476,6 +500,8 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
476500 const bool is_main_prog = !bpf_is_subprog (prog );
477501 const u8 fp = bpf2a64 [BPF_REG_FP ];
478502 const u8 arena_vm_base = bpf2a64 [ARENA_VM_START ];
503+ const u8 priv_sp = bpf2a64 [PRIVATE_SP ];
504+ void __percpu * priv_stack_ptr ;
479505 const int idx0 = ctx -> idx ;
480506 int cur_offset ;
481507
@@ -551,15 +577,23 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
551577 emit (A64_SUB_I (1 , A64_SP , A64_FP , 96 ), ctx );
552578 }
553579
554- if (ctx -> fp_used )
555- /* Set up BPF prog stack base register */
556- emit (A64_MOV (1 , fp , A64_SP ), ctx );
557-
558580 /* Stack must be multiples of 16B */
559581 ctx -> stack_size = round_up (prog -> aux -> stack_depth , 16 );
560582
583+ if (ctx -> fp_used ) {
584+ if (ctx -> priv_sp_used ) {
585+ /* Set up private stack pointer */
586+ priv_stack_ptr = prog -> aux -> priv_stack_ptr + PRIV_STACK_GUARD_SZ ;
587+ emit_percpu_ptr (priv_sp , priv_stack_ptr , ctx );
588+ emit (A64_ADD_I (1 , fp , priv_sp , ctx -> stack_size ), ctx );
589+ } else {
590+ /* Set up BPF prog stack base register */
591+ emit (A64_MOV (1 , fp , A64_SP ), ctx );
592+ }
593+ }
594+
561595 /* Set up function call stack */
562- if (ctx -> stack_size )
596+ if (ctx -> stack_size && ! ctx -> priv_sp_used )
563597 emit (A64_SUB_I (1 , A64_SP , A64_SP , ctx -> stack_size ), ctx );
564598
565599 if (ctx -> arena_vm_start )
@@ -623,7 +657,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
623657 emit (A64_STR64I (tcc , ptr , 0 ), ctx );
624658
625659 /* restore SP */
626- if (ctx -> stack_size )
660+ if (ctx -> stack_size && ! ctx -> priv_sp_used )
627661 emit (A64_ADD_I (1 , A64_SP , A64_SP , ctx -> stack_size ), ctx );
628662
629663 pop_callee_regs (ctx );
@@ -991,7 +1025,7 @@ static void build_epilogue(struct jit_ctx *ctx, bool was_classic)
9911025 const u8 ptr = bpf2a64 [TCCNT_PTR ];
9921026
9931027 /* We're done with BPF stack */
994- if (ctx -> stack_size )
1028+ if (ctx -> stack_size && ! ctx -> priv_sp_used )
9951029 emit (A64_ADD_I (1 , A64_SP , A64_SP , ctx -> stack_size ), ctx );
9961030
9971031 pop_callee_regs (ctx );
@@ -1120,6 +1154,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
11201154 const u8 tmp2 = bpf2a64 [TMP_REG_2 ];
11211155 const u8 fp = bpf2a64 [BPF_REG_FP ];
11221156 const u8 arena_vm_base = bpf2a64 [ARENA_VM_START ];
1157+ const u8 priv_sp = bpf2a64 [PRIVATE_SP ];
11231158 const s16 off = insn -> off ;
11241159 const s32 imm = insn -> imm ;
11251160 const int i = insn - ctx -> prog -> insnsi ;
@@ -1564,7 +1599,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
15641599 src = tmp2 ;
15651600 }
15661601 if (src == fp ) {
1567- src_adj = A64_SP ;
1602+ src_adj = ctx -> priv_sp_used ? priv_sp : A64_SP ;
15681603 off_adj = off + ctx -> stack_size ;
15691604 } else {
15701605 src_adj = src ;
@@ -1654,7 +1689,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
16541689 dst = tmp2 ;
16551690 }
16561691 if (dst == fp ) {
1657- dst_adj = A64_SP ;
1692+ dst_adj = ctx -> priv_sp_used ? priv_sp : A64_SP ;
16581693 off_adj = off + ctx -> stack_size ;
16591694 } else {
16601695 dst_adj = dst ;
@@ -1716,7 +1751,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
17161751 dst = tmp2 ;
17171752 }
17181753 if (dst == fp ) {
1719- dst_adj = A64_SP ;
1754+ dst_adj = ctx -> priv_sp_used ? priv_sp : A64_SP ;
17201755 off_adj = off + ctx -> stack_size ;
17211756 } else {
17221757 dst_adj = dst ;
@@ -1859,6 +1894,39 @@ static inline void bpf_flush_icache(void *start, void *end)
18591894 flush_icache_range ((unsigned long )start , (unsigned long )end );
18601895}
18611896
1897+ static void priv_stack_init_guard (void __percpu * priv_stack_ptr , int alloc_size )
1898+ {
1899+ int cpu , underflow_idx = (alloc_size - PRIV_STACK_GUARD_SZ ) >> 3 ;
1900+ u64 * stack_ptr ;
1901+
1902+ for_each_possible_cpu (cpu ) {
1903+ stack_ptr = per_cpu_ptr (priv_stack_ptr , cpu );
1904+ stack_ptr [0 ] = PRIV_STACK_GUARD_VAL ;
1905+ stack_ptr [1 ] = PRIV_STACK_GUARD_VAL ;
1906+ stack_ptr [underflow_idx ] = PRIV_STACK_GUARD_VAL ;
1907+ stack_ptr [underflow_idx + 1 ] = PRIV_STACK_GUARD_VAL ;
1908+ }
1909+ }
1910+
1911+ static void priv_stack_check_guard (void __percpu * priv_stack_ptr , int alloc_size ,
1912+ struct bpf_prog * prog )
1913+ {
1914+ int cpu , underflow_idx = (alloc_size - PRIV_STACK_GUARD_SZ ) >> 3 ;
1915+ u64 * stack_ptr ;
1916+
1917+ for_each_possible_cpu (cpu ) {
1918+ stack_ptr = per_cpu_ptr (priv_stack_ptr , cpu );
1919+ if (stack_ptr [0 ] != PRIV_STACK_GUARD_VAL ||
1920+ stack_ptr [1 ] != PRIV_STACK_GUARD_VAL ||
1921+ stack_ptr [underflow_idx ] != PRIV_STACK_GUARD_VAL ||
1922+ stack_ptr [underflow_idx + 1 ] != PRIV_STACK_GUARD_VAL ) {
1923+ pr_err ("BPF private stack overflow/underflow detected for prog %sx\n" ,
1924+ bpf_jit_get_prog_name (prog ));
1925+ break ;
1926+ }
1927+ }
1928+ }
1929+
18621930struct arm64_jit_data {
18631931 struct bpf_binary_header * header ;
18641932 u8 * ro_image ;
@@ -1873,7 +1941,9 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
18731941 struct bpf_binary_header * header ;
18741942 struct bpf_binary_header * ro_header ;
18751943 struct arm64_jit_data * jit_data ;
1944+ void __percpu * priv_stack_ptr = NULL ;
18761945 bool was_classic = bpf_prog_was_classic (prog );
1946+ int priv_stack_alloc_sz ;
18771947 bool tmp_blinded = false;
18781948 bool extra_pass = false;
18791949 struct jit_ctx ctx ;
@@ -1905,6 +1975,23 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
19051975 }
19061976 prog -> aux -> jit_data = jit_data ;
19071977 }
1978+ priv_stack_ptr = prog -> aux -> priv_stack_ptr ;
1979+ if (!priv_stack_ptr && prog -> aux -> jits_use_priv_stack ) {
1980+ /* Allocate actual private stack size with verifier-calculated
1981+ * stack size plus two memory guards to protect overflow and
1982+ * underflow.
1983+ */
1984+ priv_stack_alloc_sz = round_up (prog -> aux -> stack_depth , 16 ) +
1985+ 2 * PRIV_STACK_GUARD_SZ ;
1986+ priv_stack_ptr = __alloc_percpu_gfp (priv_stack_alloc_sz , 16 , GFP_KERNEL );
1987+ if (!priv_stack_ptr ) {
1988+ prog = orig_prog ;
1989+ goto out_priv_stack ;
1990+ }
1991+
1992+ priv_stack_init_guard (priv_stack_ptr , priv_stack_alloc_sz );
1993+ prog -> aux -> priv_stack_ptr = priv_stack_ptr ;
1994+ }
19081995 if (jit_data -> ctx .offset ) {
19091996 ctx = jit_data -> ctx ;
19101997 ro_image_ptr = jit_data -> ro_image ;
@@ -1928,6 +2015,9 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
19282015 ctx .user_vm_start = bpf_arena_get_user_vm_start (prog -> aux -> arena );
19292016 ctx .arena_vm_start = bpf_arena_get_kern_vm_start (prog -> aux -> arena );
19302017
2018+ if (priv_stack_ptr )
2019+ ctx .priv_sp_used = true;
2020+
19312021 /* Pass 1: Estimate the maximum image size.
19322022 *
19332023 * BPF line info needs ctx->offset[i] to be the offset of
@@ -2067,7 +2157,12 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
20672157 ctx .offset [i ] *= AARCH64_INSN_SIZE ;
20682158 bpf_prog_fill_jited_linfo (prog , ctx .offset + 1 );
20692159out_off :
2160+ if (!ro_header && priv_stack_ptr ) {
2161+ free_percpu (priv_stack_ptr );
2162+ prog -> aux -> priv_stack_ptr = NULL ;
2163+ }
20702164 kvfree (ctx .offset );
2165+ out_priv_stack :
20712166 kfree (jit_data );
20722167 prog -> aux -> jit_data = NULL ;
20732168 }
@@ -2086,6 +2181,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
20862181 goto out_off ;
20872182}
20882183
2184+ bool bpf_jit_supports_private_stack (void )
2185+ {
2186+ return true;
2187+ }
2188+
20892189bool bpf_jit_supports_kfunc_call (void )
20902190{
20912191 return true;
@@ -2931,6 +3031,8 @@ void bpf_jit_free(struct bpf_prog *prog)
29313031 if (prog -> jited ) {
29323032 struct arm64_jit_data * jit_data = prog -> aux -> jit_data ;
29333033 struct bpf_binary_header * hdr ;
3034+ void __percpu * priv_stack_ptr ;
3035+ int priv_stack_alloc_sz ;
29343036
29353037 /*
29363038 * If we fail the final pass of JIT (from jit_subprogs),
@@ -2944,6 +3046,13 @@ void bpf_jit_free(struct bpf_prog *prog)
29443046 }
29453047 hdr = bpf_jit_binary_pack_hdr (prog );
29463048 bpf_jit_binary_pack_free (hdr , NULL );
3049+ priv_stack_ptr = prog -> aux -> priv_stack_ptr ;
3050+ if (priv_stack_ptr ) {
3051+ priv_stack_alloc_sz = round_up (prog -> aux -> stack_depth , 16 ) +
3052+ 2 * PRIV_STACK_GUARD_SZ ;
3053+ priv_stack_check_guard (priv_stack_ptr , priv_stack_alloc_sz , prog );
3054+ free_percpu (prog -> aux -> priv_stack_ptr );
3055+ }
29473056 WARN_ON_ONCE (!bpf_prog_kallsyms_verify_off (prog ));
29483057 }
29493058
0 commit comments