Skip to content

Commit effe5be

Browse files
iii-iborkmann
authored andcommitted
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]> Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 7cec0b9 commit effe5be

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

arch/s390/net/bpf_jit_comp.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ static void bpf_jit_epilogue(struct bpf_jit *jit, u32 stack_depth)
594594
* stack space for the large switch statement.
595595
*/
596596
static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
597-
int i, bool extra_pass)
597+
int i, bool extra_pass, u32 stack_depth)
598598
{
599599
struct bpf_insn *insn = &fp->insnsi[i];
600600
u32 dst_reg = insn->dst_reg;
@@ -1207,7 +1207,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
12071207
*/
12081208

12091209
if (jit->seen & SEEN_STACK)
1210-
off = STK_OFF_TCCNT + STK_OFF + fp->aux->stack_depth;
1210+
off = STK_OFF_TCCNT + STK_OFF + stack_depth;
12111211
else
12121212
off = STK_OFF_TCCNT;
12131213
/* lhi %w0,1 */
@@ -1249,7 +1249,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
12491249
/*
12501250
* Restore registers before calling function
12511251
*/
1252-
save_restore_regs(jit, REGS_RESTORE, fp->aux->stack_depth);
1252+
save_restore_regs(jit, REGS_RESTORE, stack_depth);
12531253

12541254
/*
12551255
* goto *(prog->bpf_func + tail_call_start);
@@ -1519,26 +1519,26 @@ static int bpf_set_addr(struct bpf_jit *jit, int i)
15191519
* Compile eBPF program into s390x code
15201520
*/
15211521
static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp,
1522-
bool extra_pass)
1522+
bool extra_pass, u32 stack_depth)
15231523
{
15241524
int i, insn_count, lit32_size, lit64_size;
15251525

15261526
jit->lit32 = jit->lit32_start;
15271527
jit->lit64 = jit->lit64_start;
15281528
jit->prg = 0;
15291529

1530-
bpf_jit_prologue(jit, fp->aux->stack_depth);
1530+
bpf_jit_prologue(jit, stack_depth);
15311531
if (bpf_set_addr(jit, 0) < 0)
15321532
return -1;
15331533
for (i = 0; i < fp->len; i += insn_count) {
1534-
insn_count = bpf_jit_insn(jit, fp, i, extra_pass);
1534+
insn_count = bpf_jit_insn(jit, fp, i, extra_pass, stack_depth);
15351535
if (insn_count < 0)
15361536
return -1;
15371537
/* Next instruction address */
15381538
if (bpf_set_addr(jit, i + insn_count) < 0)
15391539
return -1;
15401540
}
1541-
bpf_jit_epilogue(jit, fp->aux->stack_depth);
1541+
bpf_jit_epilogue(jit, stack_depth);
15421542

15431543
lit32_size = jit->lit32 - jit->lit32_start;
15441544
lit64_size = jit->lit64 - jit->lit64_start;
@@ -1569,6 +1569,7 @@ struct s390_jit_data {
15691569
*/
15701570
struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
15711571
{
1572+
u32 stack_depth = round_up(fp->aux->stack_depth, 8);
15721573
struct bpf_prog *tmp, *orig_fp = fp;
15731574
struct bpf_binary_header *header;
15741575
struct s390_jit_data *jit_data;
@@ -1621,7 +1622,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
16211622
* - 3: Calculate program size and addrs arrray
16221623
*/
16231624
for (pass = 1; pass <= 3; pass++) {
1624-
if (bpf_jit_prog(&jit, fp, extra_pass)) {
1625+
if (bpf_jit_prog(&jit, fp, extra_pass, stack_depth)) {
16251626
fp = orig_fp;
16261627
goto free_addrs;
16271628
}
@@ -1635,7 +1636,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
16351636
goto free_addrs;
16361637
}
16371638
skip_init_ctx:
1638-
if (bpf_jit_prog(&jit, fp, extra_pass)) {
1639+
if (bpf_jit_prog(&jit, fp, extra_pass, stack_depth)) {
16391640
bpf_jit_binary_free(header);
16401641
fp = orig_fp;
16411642
goto free_addrs;

0 commit comments

Comments
 (0)