bpf, s390x: do not reload skb pointers in non-skb context
The assumption of unconditionally reloading skb pointers on
BPF helper calls where bpf_helper_changes_pkt_data() holds
true is wrong. There can be different contexts where the
BPF helper would enforce a reload such as in case of XDP.
Here, we do have a struct xdp_buff instead of struct sk_buff
as context, thus this will access garbage.
JITs only ever need to deal with cached skb pointer reload
when ld_abs/ind was seen, therefore guard the reload behind
SEEN_SKB only. Tested on s390x.
Fixes: 9db7f2b818
("s390/bpf: recache skb->data/hlen for skb_vlan_push/pop")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Родитель
2d17d8d79e
Коммит
6d59b7dbf7
|
@ -55,8 +55,7 @@ struct bpf_jit {
|
||||||
#define SEEN_LITERAL 8 /* code uses literals */
|
#define SEEN_LITERAL 8 /* code uses literals */
|
||||||
#define SEEN_FUNC 16 /* calls C functions */
|
#define SEEN_FUNC 16 /* calls C functions */
|
||||||
#define SEEN_TAIL_CALL 32 /* code uses tail calls */
|
#define SEEN_TAIL_CALL 32 /* code uses tail calls */
|
||||||
#define SEEN_SKB_CHANGE 64 /* code changes skb data */
|
#define SEEN_REG_AX 64 /* code uses constant blinding */
|
||||||
#define SEEN_REG_AX 128 /* code uses constant blinding */
|
|
||||||
#define SEEN_STACK (SEEN_FUNC | SEEN_MEM | SEEN_SKB)
|
#define SEEN_STACK (SEEN_FUNC | SEEN_MEM | SEEN_SKB)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -448,12 +447,12 @@ static void bpf_jit_prologue(struct bpf_jit *jit, u32 stack_depth)
|
||||||
EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0,
|
EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0,
|
||||||
REG_15, 152);
|
REG_15, 152);
|
||||||
}
|
}
|
||||||
if (jit->seen & SEEN_SKB)
|
if (jit->seen & SEEN_SKB) {
|
||||||
emit_load_skb_data_hlen(jit);
|
emit_load_skb_data_hlen(jit);
|
||||||
if (jit->seen & SEEN_SKB_CHANGE)
|
|
||||||
/* stg %b1,ST_OFF_SKBP(%r0,%r15) */
|
/* stg %b1,ST_OFF_SKBP(%r0,%r15) */
|
||||||
EMIT6_DISP_LH(0xe3000000, 0x0024, BPF_REG_1, REG_0, REG_15,
|
EMIT6_DISP_LH(0xe3000000, 0x0024, BPF_REG_1, REG_0, REG_15,
|
||||||
STK_OFF_SKBP);
|
STK_OFF_SKBP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -983,8 +982,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
|
||||||
EMIT2(0x0d00, REG_14, REG_W1);
|
EMIT2(0x0d00, REG_14, REG_W1);
|
||||||
/* lgr %b0,%r2: load return value into %b0 */
|
/* lgr %b0,%r2: load return value into %b0 */
|
||||||
EMIT4(0xb9040000, BPF_REG_0, REG_2);
|
EMIT4(0xb9040000, BPF_REG_0, REG_2);
|
||||||
if (bpf_helper_changes_pkt_data((void *)func)) {
|
if ((jit->seen & SEEN_SKB) &&
|
||||||
jit->seen |= SEEN_SKB_CHANGE;
|
bpf_helper_changes_pkt_data((void *)func)) {
|
||||||
/* lg %b1,ST_OFF_SKBP(%r15) */
|
/* lg %b1,ST_OFF_SKBP(%r15) */
|
||||||
EMIT6_DISP_LH(0xe3000000, 0x0004, BPF_REG_1, REG_0,
|
EMIT6_DISP_LH(0xe3000000, 0x0004, BPF_REG_1, REG_0,
|
||||||
REG_15, STK_OFF_SKBP);
|
REG_15, STK_OFF_SKBP);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче