提交 95782bf4 编写于 作者: M Markos Chandras 提交者: Ralf Baechle

MIPS: BPF: Prevent kernel fall over for >=32bit shifts

Remove BUG_ON() if the shift immediate is >=32 to avoid kernel crashes
due to malicious user input. If the shift immediate is >= 32,
we simply load the destination register with 0 since only
32-bit instructions are used by JIT so this will do the
correct thing even on MIPS64.
Signed-off-by: NMarkos 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/7179/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
上级 e5bb48b0
...@@ -151,6 +151,8 @@ static inline int optimize_div(u32 *k) ...@@ -151,6 +151,8 @@ static inline int optimize_div(u32 *k)
return 0; return 0;
} }
static inline void emit_jit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx);
/* Simply emit the instruction if the JIT memory space has been allocated */ /* Simply emit the instruction if the JIT memory space has been allocated */
#define emit_instr(ctx, func, ...) \ #define emit_instr(ctx, func, ...) \
do { \ do { \
...@@ -309,8 +311,11 @@ static inline void emit_sll(unsigned int dst, unsigned int src, ...@@ -309,8 +311,11 @@ static inline void emit_sll(unsigned int dst, unsigned int src,
unsigned int sa, struct jit_ctx *ctx) unsigned int sa, struct jit_ctx *ctx)
{ {
/* sa is 5-bits long */ /* sa is 5-bits long */
BUG_ON(sa >= BIT(5)); if (sa >= BIT(5))
emit_instr(ctx, sll, dst, src, sa); /* Shifting >= 32 results in zero */
emit_jit_reg_move(dst, r_zero, ctx);
else
emit_instr(ctx, sll, dst, src, sa);
} }
static inline void emit_srlv(unsigned int dst, unsigned int src, static inline void emit_srlv(unsigned int dst, unsigned int src,
...@@ -323,8 +328,11 @@ static inline void emit_srl(unsigned int dst, unsigned int src, ...@@ -323,8 +328,11 @@ static inline void emit_srl(unsigned int dst, unsigned int src,
unsigned int sa, struct jit_ctx *ctx) unsigned int sa, struct jit_ctx *ctx)
{ {
/* sa is 5-bits long */ /* sa is 5-bits long */
BUG_ON(sa >= BIT(5)); if (sa >= BIT(5))
emit_instr(ctx, srl, dst, src, sa); /* Shifting >= 32 results in zero */
emit_jit_reg_move(dst, r_zero, ctx);
else
emit_instr(ctx, srl, dst, src, sa);
} }
static inline void emit_slt(unsigned int dst, unsigned int src1, static inline void emit_slt(unsigned int dst, unsigned int src1,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册