Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d59b7db authored by Daniel Borkmann's avatar Daniel Borkmann Committed by Alexei Starovoitov
Browse files

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: 9db7f2b8 ("s390/bpf: recache skb->data/hlen for skb_vlan_push/pop")
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 2d17d8d7
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -55,8 +55,7 @@ struct bpf_jit {
#define SEEN_LITERAL	8	/* code uses literals */
#define SEEN_FUNC	16	/* calls C functions */
#define SEEN_TAIL_CALL	32	/* code uses tail calls */
#define SEEN_SKB_CHANGE	64	/* code changes skb data */
#define SEEN_REG_AX	128	/* code uses constant blinding */
#define SEEN_REG_AX	64	/* code uses constant blinding */
#define SEEN_STACK	(SEEN_FUNC | SEEN_MEM | SEEN_SKB)

/*
@@ -448,13 +447,13 @@ static void bpf_jit_prologue(struct bpf_jit *jit, u32 stack_depth)
			EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0,
				      REG_15, 152);
	}
	if (jit->seen & SEEN_SKB)
	if (jit->seen & SEEN_SKB) {
		emit_load_skb_data_hlen(jit);
	if (jit->seen & SEEN_SKB_CHANGE)
		/* stg %b1,ST_OFF_SKBP(%r0,%r15) */
		EMIT6_DISP_LH(0xe3000000, 0x0024, BPF_REG_1, REG_0, REG_15,
			      STK_OFF_SKBP);
	}
}

/*
 * Function epilogue
@@ -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);
		/* lgr %b0,%r2: load return value into %b0 */
		EMIT4(0xb9040000, BPF_REG_0, REG_2);
		if (bpf_helper_changes_pkt_data((void *)func)) {
			jit->seen |= SEEN_SKB_CHANGE;
		if ((jit->seen & SEEN_SKB) &&
		    bpf_helper_changes_pkt_data((void *)func)) {
			/* lg %b1,ST_OFF_SKBP(%r15) */
			EMIT6_DISP_LH(0xe3000000, 0x0004, BPF_REG_1, REG_0,
				      REG_15, STK_OFF_SKBP);