Received: by 2002:a17:90a:1609:0:0:0:0 with SMTP id n9csp125727pja; Thu, 9 Apr 2020 15:54:02 -0700 (PDT) X-Google-Smtp-Source: APiQypJAmAgBGQ6HDG4yqpQpSA9Rsh8CCqKQ3+4PHXDKAtdc2vs15foLjMXqtcBJXobrjZSoHd5t X-Received: by 2002:ac8:1a85:: with SMTP id x5mr1795233qtj.302.1586472841977; Thu, 09 Apr 2020 15:54:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1586472841; cv=none; d=google.com; s=arc-20160816; b=A6ZN32nxmaEm282fsOyuGxYczaDlHPGyH+bmRztMeCPZg785mg4jc5r5Mgz+3U6mCQ 0PCE3J7/+Z6i5GjNV8dc73FWOR8dy/XlKI07SmeFtJUVBezr93m/4y3SRB/hqyYD71Kl 88O3S76MpXiPiLM/xnTfsD9AHoTwLj2sgXTqhrljSJVyxzFap//i0U/PrTOcxM3eLcwN Cow1mGQ1g8ZaTfAzZk/TdxDAetpk22ub0G/oQ7Sjo4i1wFSLfPLw6nb+ha6E5ZDT1ZDd 6OWC4M5TwsO3QgJEfwCqkZGmFjRdCubQyYD8qJqsN5ZiYTBQH87NrvefF0pH4s5xb2o6 2WPQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature; bh=d7I79Px6oW+xidqJy+si2tmnAYd369ZVNNbYLDl32gU=; b=JiklJaPhjCnbsVbfuiZeOTA1mCu9FKKWDYvXK5qOiiglTjyyJHMad4zYkRAHVberMQ sNZmDtAkzRXqiwDQ4a+54y1SyZ11T8JFMiMyNVFgLLNFK+lq1da2fKKcNeF6Hu7mVN5A Lw+KYvEHLvwYecpF+XGJeL2+bgGCRCn5GiOiXIl5lhUwBNDIkDsRAiyBFPsdKHcsrhoK xT6qgpXuREqFY7+c/qaqwmZGybu/P1/xa1TvyBMCzQNOMNzvjqX0R7kXQGIRiZXEIZlZ XWAa0NSsLWFF/343yhKRvG0J0cjPfrChJkG00ouH2FlZYxfyz+uE2HfQ0tuSwySMRjTk MJJw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cs.washington.edu header.s=goo201206 header.b=W9vJOxKo; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cs.washington.edu Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z25si285027qkg.341.2020.04.09.15.52.51; Thu, 09 Apr 2020 15:54:01 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@cs.washington.edu header.s=goo201206 header.b=W9vJOxKo; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cs.washington.edu Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726830AbgDIWSE (ORCPT + 99 others); Thu, 9 Apr 2020 18:18:04 -0400 Received: from mail-pj1-f68.google.com ([209.85.216.68]:36891 "EHLO mail-pj1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726632AbgDIWSE (ORCPT ); Thu, 9 Apr 2020 18:18:04 -0400 Received: by mail-pj1-f68.google.com with SMTP id z9so63722pjd.2 for ; Thu, 09 Apr 2020 15:18:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cs.washington.edu; s=goo201206; h=from:to:cc:subject:date:message-id; bh=d7I79Px6oW+xidqJy+si2tmnAYd369ZVNNbYLDl32gU=; b=W9vJOxKo91GTrNMNOMDe+CcYIVgw/SOaLir7ekED0M2QDlKPHJMg0FkVS8aK5M4xUT wKcgwDjPlpAbpIDBkQwzvxwo3aVhwKRbg73R/ocWLnP1YHT83chblwRCKlYUk3f3QcHv X6rglaZaHPq7Yu0iL3vU0s8SY7n3uOxzM0y4Y= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=d7I79Px6oW+xidqJy+si2tmnAYd369ZVNNbYLDl32gU=; b=ugE6ZztoNWoeYLduc6MEWz7WH2pkxWja6IB4T0dEioDRIJoq4WLxaJfJwLDYtFxxPm /VpTcstoKJco56Vx7ePEotPhXXTuf1KpxyEJ4H5pvfh6lZ02iO+wnE4XXrCKfpjY6KI0 cvyQNaaWLdDkGjiyN8BkQOExY5a7nvr3ZIIXFZjHiVL3iJ4vWzLi1/cxJ0vis9Jw2MwO W/py71dz6F5vAWyMJsly7gjR2t0czSpLEwBdrUlHoV3g7zFUCwMNnm2aLyVI8rPL5Tt+ jTX22rPqnlhqXTYS56ZiXF0fVO2GYRUi78jxYlStsh9uBjU/U6xqWZMGmbu9sbK0hdeM bxvA== X-Gm-Message-State: AGi0PuaapBLSpLZ4Z0J9ajRJxe4VGyv+q4jYvUA2rA6RBcGwe4RYKO3O DHcK3Oe70QQcq8N7Tq4pnq2kaw== X-Received: by 2002:a17:90a:94c8:: with SMTP id j8mr1817350pjw.155.1586470682925; Thu, 09 Apr 2020 15:18:02 -0700 (PDT) Received: from localhost.localdomain (c-73-53-94-119.hsd1.wa.comcast.net. [73.53.94.119]) by smtp.gmail.com with ESMTPSA id w29sm111547pge.25.2020.04.09.15.18.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Apr 2020 15:18:02 -0700 (PDT) From: Luke Nelson X-Google-Original-From: Luke Nelson To: bpf@vger.kernel.org Cc: Luke Nelson , Xi Wang , Shubham Bansal , Russell King , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andrii Nakryiko , John Fastabend , KP Singh , netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH bpf] arm, bpf: Fix offset overflow for BPF_MEM BPF_DW Date: Thu, 9 Apr 2020 15:17:52 -0700 Message-Id: <20200409221752.28448-1-luke.r.nels@gmail.com> X-Mailer: git-send-email 2.17.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch fixes an incorrect check in how immediate memory offsets are computed for BPF_DW on arm. For BPF_LDX/ST/STX + BPF_DW, the 32-bit arm JIT breaks down an 8-byte access into two separate 4-byte accesses using off+0 and off+4. If off fits in imm12, the JIT emits a ldr/str instruction with the immediate and avoids the use of a temporary register. While the current check off <= 0xfff ensures that the first immediate off+0 doesn't overflow imm12, it's not sufficient for the second immediate off+4, which may cause the second access of BPF_DW to read/write the wrong address. This patch fixes the problem by changing the check to off <= 0xfff - 4 for BPF_DW, ensuring off+4 will never overflow. A side effect of simplifying the check is that it now allows using negative immediate offsets in ldr/str. This means that small negative offsets can also avoid the use of a temporary register. This patch introduces no new failures in test_verifier or test_bpf.c. Fixes: c5eae692571d6 ("ARM: net: bpf: improve 64-bit store implementation") Fixes: ec19e02b343db ("ARM: net: bpf: fix LDX instructions") Co-developed-by: Xi Wang Signed-off-by: Xi Wang Signed-off-by: Luke Nelson --- arch/arm/net/bpf_jit_32.c | 40 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index d124f78e20ac..bf85d6db4931 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -1000,21 +1000,35 @@ static inline void emit_a32_mul_r64(const s8 dst[], const s8 src[], arm_bpf_put_reg32(dst_hi, rd[0], ctx); } +static bool is_ldst_imm(s16 off, const u8 size) +{ + s16 off_max = 0; + + switch (size) { + case BPF_B: + case BPF_W: + off_max = 0xfff; + break; + case BPF_H: + off_max = 0xff; + break; + case BPF_DW: + /* Need to make sure off+4 does not overflow. */ + off_max = 0xfff - 4; + break; + } + return -off_max <= off && off <= off_max; +} + /* *(size *)(dst + off) = src */ static inline void emit_str_r(const s8 dst, const s8 src[], - s32 off, struct jit_ctx *ctx, const u8 sz){ + s16 off, struct jit_ctx *ctx, const u8 sz){ const s8 *tmp = bpf2a32[TMP_REG_1]; - s32 off_max; s8 rd; rd = arm_bpf_get_reg32(dst, tmp[1], ctx); - if (sz == BPF_H) - off_max = 0xff; - else - off_max = 0xfff; - - if (off < 0 || off > off_max) { + if (!is_ldst_imm(off, sz)) { emit_a32_mov_i(tmp[0], off, ctx); emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx); rd = tmp[0]; @@ -1043,18 +1057,12 @@ static inline void emit_str_r(const s8 dst, const s8 src[], /* dst = *(size*)(src + off) */ static inline void emit_ldx_r(const s8 dst[], const s8 src, - s32 off, struct jit_ctx *ctx, const u8 sz){ + s16 off, struct jit_ctx *ctx, const u8 sz){ const s8 *tmp = bpf2a32[TMP_REG_1]; const s8 *rd = is_stacked(dst_lo) ? tmp : dst; s8 rm = src; - s32 off_max; - - if (sz == BPF_H) - off_max = 0xff; - else - off_max = 0xfff; - if (off < 0 || off > off_max) { + if (!is_ldst_imm(off, sz)) { emit_a32_mov_i(tmp[0], off, ctx); emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx); rm = tmp[0]; -- 2.17.1