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

Commit 55393ee5 authored by Markos Chandras's avatar Markos Chandras Committed by Ralf Baechle
Browse files

MIPS: bpf: Return error code if the offset is a negative number



Previously, the negative offset was not checked leading to failures
due to trying to load data beyond the skb struct boundaries. Until we
have proper asm helpers in place, it's best if we return ENOSUPP if K
is negative when trying to JIT the filter or 0 during runtime if we
do an indirect load where the value of X is unknown during build time.

Signed-off-by: default avatarMarkos Chandras <markos.chandras@imgtec.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Daniel Borkmann <dborkman@redhat.com>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: netdev@vger.kernel.org
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/7123/


Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 35a8e16a
Loading
Loading
Loading
Loading
+23 −0
Original line number Original line Diff line number Diff line
@@ -331,6 +331,12 @@ static inline void emit_srl(unsigned int dst, unsigned int src,
	emit_instr(ctx, srl, dst, src, sa);
	emit_instr(ctx, srl, dst, src, sa);
}
}


static inline void emit_slt(unsigned int dst, unsigned int src1,
			    unsigned int src2, struct jit_ctx *ctx)
{
	emit_instr(ctx, slt, dst, src1, src2);
}

static inline void emit_sltu(unsigned int dst, unsigned int src1,
static inline void emit_sltu(unsigned int dst, unsigned int src1,
			     unsigned int src2, struct jit_ctx *ctx)
			     unsigned int src2, struct jit_ctx *ctx)
{
{
@@ -816,8 +822,21 @@ static int build_body(struct jit_ctx *ctx)
			/* A <- P[k:1] */
			/* A <- P[k:1] */
			load_order = 0;
			load_order = 0;
load:
load:
			/* the interpreter will deal with the negative K */
			if ((int)k < 0)
				return -ENOTSUPP;

			emit_load_imm(r_off, k, ctx);
			emit_load_imm(r_off, k, ctx);
load_common:
load_common:
			/*
			 * We may got here from the indirect loads so
			 * return if offset is negative.
			 */
			emit_slt(r_s0, r_off, r_zero, ctx);
			emit_bcond(MIPS_COND_NE, r_s0, r_zero,
				   b_imm(prog->len, ctx), ctx);
			emit_reg_move(r_ret, r_zero, ctx);

			ctx->flags |= SEEN_CALL | SEEN_OFF | SEEN_S0 |
			ctx->flags |= SEEN_CALL | SEEN_OFF | SEEN_S0 |
				SEEN_SKB | SEEN_A;
				SEEN_SKB | SEEN_A;


@@ -880,6 +899,10 @@ static int build_body(struct jit_ctx *ctx)
			emit_load(r_X, r_skb, off, ctx);
			emit_load(r_X, r_skb, off, ctx);
			break;
			break;
		case BPF_LDX | BPF_B | BPF_MSH:
		case BPF_LDX | BPF_B | BPF_MSH:
			/* the interpreter will deal with the negative K */
			if ((int)k < 0)
				return -ENOTSUPP;

			/* X <- 4 * (P[k:1] & 0xf) */
			/* X <- 4 * (P[k:1] & 0xf) */
			ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB;
			ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB;
			/* Load offset to a1 */
			/* Load offset to a1 */