aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/net/bpf_jit.c
diff options
context:
space:
mode:
authorMarkos Chandras <markos.chandras@imgtec.com>2014-06-23 05:38:48 -0400
committerRalf Baechle <ralf@linux-mips.org>2014-06-26 05:48:20 -0400
commit55393ee535496f7db15f3b2e9d3cf418f772f71a (patch)
tree92efeccf3e43e6caf9f11a87576d9fb21b7f5d1b /arch/mips/net/bpf_jit.c
parent35a8e16abe36d385d602997e1500a668d2b9c5cf (diff)
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: Markos 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: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/net/bpf_jit.c')
-rw-r--r--arch/mips/net/bpf_jit.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c
index 5cc92c4590cb..95728ea6cb74 100644
--- a/arch/mips/net/bpf_jit.c
+++ b/arch/mips/net/bpf_jit.c
@@ -331,6 +331,12 @@ static inline void emit_srl(unsigned int dst, unsigned int src,
331 emit_instr(ctx, srl, dst, src, sa); 331 emit_instr(ctx, srl, dst, src, sa);
332} 332}
333 333
334static inline void emit_slt(unsigned int dst, unsigned int src1,
335 unsigned int src2, struct jit_ctx *ctx)
336{
337 emit_instr(ctx, slt, dst, src1, src2);
338}
339
334static inline void emit_sltu(unsigned int dst, unsigned int src1, 340static inline void emit_sltu(unsigned int dst, unsigned int src1,
335 unsigned int src2, struct jit_ctx *ctx) 341 unsigned int src2, struct jit_ctx *ctx)
336{ 342{
@@ -816,8 +822,21 @@ static int build_body(struct jit_ctx *ctx)
816 /* A <- P[k:1] */ 822 /* A <- P[k:1] */
817 load_order = 0; 823 load_order = 0;
818load: 824load:
825 /* the interpreter will deal with the negative K */
826 if ((int)k < 0)
827 return -ENOTSUPP;
828
819 emit_load_imm(r_off, k, ctx); 829 emit_load_imm(r_off, k, ctx);
820load_common: 830load_common:
831 /*
832 * We may got here from the indirect loads so
833 * return if offset is negative.
834 */
835 emit_slt(r_s0, r_off, r_zero, ctx);
836 emit_bcond(MIPS_COND_NE, r_s0, r_zero,
837 b_imm(prog->len, ctx), ctx);
838 emit_reg_move(r_ret, r_zero, ctx);
839
821 ctx->flags |= SEEN_CALL | SEEN_OFF | SEEN_S0 | 840 ctx->flags |= SEEN_CALL | SEEN_OFF | SEEN_S0 |
822 SEEN_SKB | SEEN_A; 841 SEEN_SKB | SEEN_A;
823 842
@@ -880,6 +899,10 @@ load_ind:
880 emit_load(r_X, r_skb, off, ctx); 899 emit_load(r_X, r_skb, off, ctx);
881 break; 900 break;
882 case BPF_LDX | BPF_B | BPF_MSH: 901 case BPF_LDX | BPF_B | BPF_MSH:
902 /* the interpreter will deal with the negative K */
903 if ((int)k < 0)
904 return -ENOTSUPP;
905
883 /* X <- 4 * (P[k:1] & 0xf) */ 906 /* X <- 4 * (P[k:1] & 0xf) */
884 ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB; 907 ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB;
885 /* Load offset to a1 */ 908 /* Load offset to a1 */