Message ID | 20200506195138.22086-6-broonie@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | arm64: BTI kernel and vDSO support | expand |
[ Cc +bpf ] On 5/6/20 9:51 PM, Mark Brown wrote: > In order to extend the protection offered by BTI to all code executing in > kernel mode we need to annotate JITed BPF code appropriately for BTI. To > do this we need to add a landing pad to the start of each BPF function and > also immediately after the function prologue if we are emitting a function > which can be tail called. Jumps within BPF functions are all to immediate > offsets and therefore do not require landing pads. > > Signed-off-by: Mark Brown <broonie@kernel.org> > Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> > --- > arch/arm64/net/bpf_jit.h | 8 ++++++++ > arch/arm64/net/bpf_jit_comp.c | 12 ++++++++++++ > 2 files changed, 20 insertions(+) > > diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h > index eb73f9f72c46..05b477709b5f 100644 > --- a/arch/arm64/net/bpf_jit.h > +++ b/arch/arm64/net/bpf_jit.h > @@ -189,4 +189,12 @@ > /* Rn & Rm; set condition flags */ > #define A64_TST(sf, Rn, Rm) A64_ANDS(sf, A64_ZR, Rn, Rm) > > +/* HINTs */ > +#define A64_HINT(x) aarch64_insn_gen_hint(x) > + > +/* BTI */ > +#define A64_BTI_C A64_HINT(AARCH64_INSN_HINT_BTIC) > +#define A64_BTI_J A64_HINT(AARCH64_INSN_HINT_BTIJ) > +#define A64_BTI_JC A64_HINT(AARCH64_INSN_HINT_BTIJC) > + > #endif /* _BPF_JIT_H */ > diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c > index cdc79de0c794..83fa475c6b42 100644 > --- a/arch/arm64/net/bpf_jit_comp.c > +++ b/arch/arm64/net/bpf_jit_comp.c > @@ -171,7 +171,11 @@ static inline int epilogue_offset(const struct jit_ctx *ctx) > #define STACK_ALIGN(sz) (((sz) + 15) & ~15) > > /* Tail call offset to jump into */ > +#if IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) > +#define PROLOGUE_OFFSET 8 > +#else > #define PROLOGUE_OFFSET 7 > +#endif > > static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) > { > @@ -208,6 +212,10 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) > * > */ > > + /* BTI landing pad */ > + if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) > + emit(A64_BTI_C, ctx); > + > /* Save FP and LR registers to stay align with ARM64 AAPCS */ > emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx); > emit(A64_MOV(1, A64_FP, A64_SP), ctx); > @@ -230,6 +238,10 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) > cur_offset, PROLOGUE_OFFSET); > return -1; > } > + > + /* BTI landing pad for the tail call, done with a BR */ > + if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) > + emit(A64_BTI_J, ctx); > } > > ctx->stack_size = STACK_ALIGN(prog->aux->stack_depth); >
diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h index eb73f9f72c46..05b477709b5f 100644 --- a/arch/arm64/net/bpf_jit.h +++ b/arch/arm64/net/bpf_jit.h @@ -189,4 +189,12 @@ /* Rn & Rm; set condition flags */ #define A64_TST(sf, Rn, Rm) A64_ANDS(sf, A64_ZR, Rn, Rm) +/* HINTs */ +#define A64_HINT(x) aarch64_insn_gen_hint(x) + +/* BTI */ +#define A64_BTI_C A64_HINT(AARCH64_INSN_HINT_BTIC) +#define A64_BTI_J A64_HINT(AARCH64_INSN_HINT_BTIJ) +#define A64_BTI_JC A64_HINT(AARCH64_INSN_HINT_BTIJC) + #endif /* _BPF_JIT_H */ diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index cdc79de0c794..83fa475c6b42 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -171,7 +171,11 @@ static inline int epilogue_offset(const struct jit_ctx *ctx) #define STACK_ALIGN(sz) (((sz) + 15) & ~15) /* Tail call offset to jump into */ +#if IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) +#define PROLOGUE_OFFSET 8 +#else #define PROLOGUE_OFFSET 7 +#endif static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) { @@ -208,6 +212,10 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) * */ + /* BTI landing pad */ + if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) + emit(A64_BTI_C, ctx); + /* Save FP and LR registers to stay align with ARM64 AAPCS */ emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx); emit(A64_MOV(1, A64_FP, A64_SP), ctx); @@ -230,6 +238,10 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) cur_offset, PROLOGUE_OFFSET); return -1; } + + /* BTI landing pad for the tail call, done with a BR */ + if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)) + emit(A64_BTI_J, ctx); } ctx->stack_size = STACK_ALIGN(prog->aux->stack_depth);