From patchwork Tue Jan 5 17:39:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rabin Vincent X-Patchwork-Id: 563213 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id D689C1402EC for ; Wed, 6 Jan 2016 04:39:14 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=zMXwTYCN; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752253AbcAERjK (ORCPT ); Tue, 5 Jan 2016 12:39:10 -0500 Received: from mail-wm0-f44.google.com ([74.125.82.44]:34690 "EHLO mail-wm0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752133AbcAERjI (ORCPT ); Tue, 5 Jan 2016 12:39:08 -0500 Received: by mail-wm0-f44.google.com with SMTP id u188so32120979wmu.1 for ; Tue, 05 Jan 2016 09:39:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id; bh=lRVSX0CBox/LJKzAmhuWjsVi534HrhB+JDJiI19qphA=; b=zMXwTYCNVba1QsPNYIIYyRs5TKs6MVbmqikdeQ6xz745t7QZzlC0bBVyjd+nte/TNW +0AfwFYfuyMe9AObJuUJpKYyKSC04yBKheTrhe703zfKzM//v97S6XXLuj+YTTjb9gFO 7aGlXUqkpQ71XmElD71O/SAday/MlXHchChR3uv5pwYBg0TPAzCSaF4yXQGQHD41zE0D zt+BQtWKEreMmwB9U9uvrrxszyZNv8ZepC/QfRsUTtVoirvV+uCYc8zgoCpPDd9I0fhm 2qPB9UJFjEkrfEtJcPJ0Syrqo6DQJK9qIaPSFLi1jXSXy7E68l1LpXkjiTEtAkZ1g+53 owtA== X-Received: by 10.28.19.76 with SMTP id 73mr1083205wmt.24.1452015547754; Tue, 05 Jan 2016 09:39:07 -0800 (PST) Received: from localhost.localdomain (h249n21-ld-c-a31.ias.bredband.telia.com. [78.70.84.249]) by smtp.gmail.com with ESMTPSA id s129sm4563002wmf.18.2016.01.05.09.39.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Jan 2016 09:39:07 -0800 (PST) From: Rabin Vincent To: davem@davemloft.net Cc: netdev@vger.kernel.org, zlim.lnx@gmail.com, yang.shi@linaro.org, will.deacon@arm.com, catalin.marinas@arm.com, linux-arm-kernel@lists.infradead.org, Rabin Vincent Subject: [PATCH] arm64: net: bpf: don't BUG() on large shifts Date: Tue, 5 Jan 2016 18:39:03 +0100 Message-Id: <1452015543-6790-1-git-send-email-rabin@rab.in> X-Mailer: git-send-email 2.6.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Attempting to generate UBFM/SBFM instructions with shifts that can't be encoded in the immediate fields of the opcodes leads to a trigger of a BUG() in the instruction generation code. As the ARMv8 ARM says: "The shift amounts must be in the range 0 to one less than the register width of the instruction, inclusive." Make the JIT reject unencodable shifts instead of crashing. ------------[ cut here ]------------ kernel BUG at arch/arm64/kernel/insn.c:766! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP CPU: 0 PID: 669 Comm: insmod Not tainted 4.4.0-rc8+ #4 PC is at aarch64_insn_gen_bitfield+0xcc/0xd4 LR is at build_body+0x1000/0x2914 .. Call trace: [] aarch64_insn_gen_bitfield+0xcc/0xd4 [] build_body+0x1000/0x2914 [] bpf_int_jit_compile+0x7c/0x1b4 [] bpf_prog_select_runtime+0x20/0xcc [] bpf_prepare_filter+0x3d8/0x3e8 [] bpf_prog_create+0x74/0xa4 [] test_bpf_init+0x1d4/0x748 [test_bpf] [] do_one_initcall+0x90/0x1a8 [] do_init_module+0x60/0x1c8 [] load_module+0x1554/0x1c98 [] SyS_init_module+0x11c/0x140 [] el0_svc_naked+0x24/0x28 Signed-off-by: Rabin Vincent --- arch/arm64/net/bpf_jit_comp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index b162ad70effc..3f4f089a85c0 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -255,6 +255,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) const s32 imm = insn->imm; const int i = insn - ctx->prog->insnsi; const bool is64 = BPF_CLASS(code) == BPF_ALU64; + const int bits = is64 ? 64 : 32; u8 jmp_cond; s32 jmp_offset; @@ -444,14 +445,20 @@ emit_bswap_uxt: break; case BPF_ALU | BPF_LSH | BPF_K: case BPF_ALU64 | BPF_LSH | BPF_K: + if (imm < 0 || imm >= bits) + return -EINVAL; emit(A64_LSL(is64, dst, dst, imm), ctx); break; case BPF_ALU | BPF_RSH | BPF_K: case BPF_ALU64 | BPF_RSH | BPF_K: + if (imm < 0 || imm >= bits) + return -EINVAL; emit(A64_LSR(is64, dst, dst, imm), ctx); break; case BPF_ALU | BPF_ARSH | BPF_K: case BPF_ALU64 | BPF_ARSH | BPF_K: + if (imm < 0 || imm >= bits) + return -EINVAL; emit(A64_ASR(is64, dst, dst, imm), ctx); break;