s390/bpf: Maintain 8-byte stack alignment
Subsystems (3)
Ilya Leoshkevich
maintainerPATCH 1/1 s390/bpf: Maintain 8-byte stack alignment
Certain kernel functions (e.g. get_vtimer/set_vtimer) cause kernel panic when the stack is not 8-byte aligned. Currently JITed BPF programs may trigger this by allocating stack frames with non-rounded sizes and then being interrupted. Fix by using rounded fp->aux->stack_depth.
Signed-off-by Ilya Leoshkevich <[email protected]>
--- arch/s390/net/bpf_jit_comp.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
arch/s390/net/bpf_jit_comp.c +10 -9
@@ -594,7 +594,7 @@ static void bpf_jit_epilogue(struct bpf_jit *jit, u32 stack_depth)* stack space for the large switch statement. */ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, -int i,bool extra_pass) +int i,bool extra_pass,u32 stack_depth) {struct bpf_insn *insn = &fp->insnsi[i];u32 dst_reg = insn->dst_reg;
@@ -1207,7 +1207,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,*/ if (jit->seen &SEEN_STACK ) - off =STK_OFF_TCCNT +STK_OFF + fp->aux->stack_depth; + off =STK_OFF_TCCNT +STK_OFF + stack_depth;else off =STK_OFF_TCCNT ;/* lhi %w0,1 */
@@ -1249,7 +1249,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,/* * Restore registers before calling function */ -save_restore_regs (jit,REGS_RESTORE , fp->aux->stack_depth); +save_restore_regs (jit,REGS_RESTORE , stack_depth);/* * goto *(prog->bpf_func + tail_call_start);
@@ -1519,7 +1519,7 @@ static int bpf_set_addr(struct bpf_jit *jit, int i)* Compile eBPF program into s390x code */ static int bpf_jit_prog (struct bpf_jit *jit,struct bpf_prog *fp, -bool extra_pass) +bool extra_pass,u32 stack_depth) {int i, insn_count, lit32_size, lit64_size;
@@ -1527,18 +1527,18 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp, jit->lit64 = jit->lit64_start; jit->prg =0 ; -bpf_jit_prologue (jit, fp->aux->stack_depth); +bpf_jit_prologue (jit, stack_depth);if (bpf_set_addr (jit,0 ) <0 )return -1 ;for (i =0 ; i < fp->len; i += insn_count) { - insn_count =bpf_jit_insn (jit, fp, i, extra_pass); + insn_count =bpf_jit_insn (jit, fp, i, extra_pass, stack_depth);if (insn_count <0 )return -1 ;/* Next instruction address */ if (bpf_set_addr (jit, i + insn_count) <0 )return -1 ; } -bpf_jit_epilogue (jit, fp->aux->stack_depth); +bpf_jit_epilogue (jit, stack_depth); lit32_size = jit->lit32 - jit->lit32_start; lit64_size = jit->lit64 - jit->lit64_start;
@@ -1569,6 +1569,7 @@ struct s390_jit_data {*/ struct bpf_prog *bpf_int_jit_compile (struct bpf_prog *fp) { +u32 stack_depth =round_up (fp->aux->stack_depth,8 );struct bpf_prog *tmp, *orig_fp = fp;struct bpf_binary_header *header;struct s390_jit_data *jit_data;
@@ -1621,7 +1622,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)* - 3: Calculate program size and addrs arrray */ for (pass =1 ; pass <=3 ; pass++) { -if (bpf_jit_prog (&jit, fp, extra_pass)) { +if (bpf_jit_prog (&jit, fp, extra_pass, stack_depth)) { fp = orig_fp; goto free_addrs; }
@@ -1635,7 +1636,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) goto free_addrs; } skip_init_ctx: -if (bpf_jit_prog (&jit, fp, extra_pass)) { +if (bpf_jit_prog (&jit, fp, extra_pass, stack_depth)) {bpf_jit_binary_free (header); fp = orig_fp; goto free_addrs;
Signature · 1 line
2.25.4
Quoted 6 lines · Ilya Leoshkevich
Certain kernel functions (e.g. get_vtimer/set_vtimer) cause kernel panic when the stack is not 8-byte aligned. Currently JITed BPF programs may trigger this by allocating stack frames with non-rounded sizes and then being interrupted. Fix by using rounded
fp->aux->stack_depth.Signed-off-by Ilya Leoshkevich <[email protected]>
Applied, thanks!