Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp4898142imm; Wed, 30 May 2018 14:24:24 -0700 (PDT) X-Google-Smtp-Source: ADUXVKKw5J+UZhozQLO4AP6MJpjFaMiDLb4b/VtbOaddfBx7XfGh2nG/z/zM77QynWGERAiUpZqY X-Received: by 2002:a62:50d6:: with SMTP id g83-v6mr4209973pfj.31.1527715464545; Wed, 30 May 2018 14:24:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527715464; cv=none; d=google.com; s=arc-20160816; b=k43/ZuPgFfYZh3GvhmbGdz1rd3EQy7e/cgryBTxsMx6tPnJRHk3o9KNHm3hd2bDdnf kCkQGXra5hDm8zvqg/VtLaGcYhrYx1ue3hxFRiAkupIejDoawMFbDS+0tgf9nmdcxRpK +4tILv7iadNFD/aavfoLhwN8m5axro6tiYhlgFJz1ezieYHspXlaemjVXk1iq953pkum 9+Zgj79m0OYH1DhBH9tb4KlzlSkLvTdFchMI+6zuHZwqkW+RAkH2WhvWCUIHECbalh9x K6jaaEXeFMF5tP6IXNQHnbAmmrYKAcSF5DfAK94Xb/uoC33GLaWDzcSIhNohS4NOC0qJ rL1A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-disposition:mime-version:message-id:subject:cc:to:from:date :dkim-signature:arc-authentication-results; bh=oHvaAH9w0DLlrNC4Lq3pmRyl4GkKxxuHMnZww7V0UM0=; b=L6sK/prjOj2MBV6lmNQykOFXVs8UbJM3GHxxDjGlZeE4OBgw6XjhYL7i0CrdHQr5/C B4xoMBabOUUnvbBiyMJhOtogsph9MR+md8qkj/jkGfaIDNid3sUCWJ4LpFmSsr5ej8kV N1vJDtGEg/q3r2mGAvWxxzpCuFSupodNySElE9tWn7kTAAdEnNA5ONUWJp1FKxl0BW11 jv4juA1BublNI+KyvgIT5lu5wxzpNEKx6v6Bpgyr4Ryf+DU2WctuNhL8CWpgce9udezZ +ssgxtdvO1M7a0ArklPHbB8LL0DUKKC1QOPL/Zp5Gly992g/d0kcvce6D5DpoWEXpP+V 4iVA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=VqWbyS5Y; 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=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d203-v6si7133691pfd.182.2018.05.30.14.24.10; Wed, 30 May 2018 14:24:24 -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=@chromium.org header.s=google header.b=VqWbyS5Y; 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=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932373AbeE3VWL (ORCPT + 99 others); Wed, 30 May 2018 17:22:11 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:38506 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932268AbeE3VWJ (ORCPT ); Wed, 30 May 2018 17:22:09 -0400 Received: by mail-pf0-f193.google.com with SMTP id b74-v6so6195394pfl.5 for ; Wed, 30 May 2018 14:22:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :content-transfer-encoding; bh=oHvaAH9w0DLlrNC4Lq3pmRyl4GkKxxuHMnZww7V0UM0=; b=VqWbyS5YnSnNawnOUaEymrh9nfVoaSle0UmdZgYHZroEBN02lCKue6AIeGmXJQovoP DdCGxaTX4l0EMphMcuBPdrdmfCLI5sFS9lIJ7LUAPykP6xgEkvfcuobiraX7BS9z5Egn my6AJzT16BhLiJyiG0EGUJny2FnX0nV6w3fWc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:content-transfer-encoding; bh=oHvaAH9w0DLlrNC4Lq3pmRyl4GkKxxuHMnZww7V0UM0=; b=FEGqUSMSNR8KbIiTMNs+kWyKHZEKSwJxaWzyiPuHAEPigIdBuqWnSruWqAkwizVLOB QRTjMw8VlEjz832bT1DG1z5HB42bSzWPdx9anzXw9lgvMDjHiIN9j7Jz6hiCK9EnwBJ2 6100sBYWxkjibBFjr7wCGZeHazdM3odo5xgVcqQdxwDEpisPvsFAo6JIgSiFMAEnIXiS UokjW8ADydVbUzl6JsLqaE/TcnvCXsX2OmH1+GO+0GCXFppSPXhA2CEHoRw2w0L8K5bD 7ZcWPEfjIzPoeLGlWxTU7q5QTkgIdIXTP2KBWEwI6AHS/cQrOvVsIuETyCuVgvp4GV/Z eq7Q== X-Gm-Message-State: ALKqPwev1eSZa4LpCkRnLnV7mTvH6SKy9UBSuD5Veo41dKlKpThlaJOi JKQ2ZudaIqWhQzFrXpdPtxP9PA== X-Received: by 2002:a62:4f4f:: with SMTP id d76-v6mr4194456pfb.188.1527715328508; Wed, 30 May 2018 14:22:08 -0700 (PDT) Received: from www.outflux.net (173-164-112-133-Oregon.hfc.comcastbusiness.net. [173.164.112.133]) by smtp.gmail.com with ESMTPSA id y18-v6sm74829422pfi.104.2018.05.30.14.22.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 30 May 2018 14:22:07 -0700 (PDT) Date: Wed, 30 May 2018 14:22:06 -0700 From: Kees Cook To: Ivan Djelic Cc: Boris Brezillon , Brian Norris , David Woodhouse , Marek Vasut , Richard Weinberger , Linux mtd , LKML Subject: [PATCH v2] lib/bch: Remove VLA usage Message-ID: <20180530212206.GA36883@beast> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In the quest to remove all stack VLA usage from the kernel[1], this allocates a fixed size stack array to cover the range needed for bch. This was done instead of a preallocation on the SLAB due to performance reasons, shown by Ivan Djelic: little-endian, type sizes: int=4 long=8 longlong=8 cpu: Intel(R) Core(TM) i5 CPU         650  @ 3.20GHz calibration: iter=4.9143µs niter=2034 nsamples=200 m=13 t=4   Buffer allocation |  Encoding throughput (Mbit/s) ---------------------------------------------------  on-stack, VLA      |   3988  on-stack, fixed    |   4494  kmalloc            |   1967 So this change actually improves performance too, it seems. The resulting stack allocation can get rather large; without CONFIG_BCH_CONST_PARAMS, it will allocate 4096 bytes, which trips the stack size checking: lib/bch.c: In function ‘encode_bch’: lib/bch.c:261:1: warning: the frame size of 4432 bytes is larger than 2048 bytes [-Wframe-larger-than=] Even the default case for "allmodconfig" (with CONFIG_BCH_CONST_M=14 and CONFIG_BCH_CONST_T=4) would have started throwing a warning: lib/bch.c: In function ‘encode_bch’: lib/bch.c:261:1: warning: the frame size of 2288 bytes is larger than 2048 bytes [-Wframe-larger-than=] But this is how large it's always been; it was just hidden from the checker because it was a VLA. So the Makefile has been adjusted to silence this warning for anything smaller than 4500 bytes, which should provide room for normal cases, but still low enough to catch any future pathological situations. [1] https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com Signed-off-by: Kees Cook --- v2: switch to fixed-size stack array --- lib/Makefile | 1 + lib/bch.c | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index ce20696d5a92..24331b122d7f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -121,6 +121,7 @@ obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/ obj-$(CONFIG_REED_SOLOMON) += reed_solomon/ obj-$(CONFIG_BCH) += bch.o +CFLAGS_bch.o := $(call cc-option,-Wframe-larger-than=4500) obj-$(CONFIG_LZO_COMPRESS) += lzo/ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ obj-$(CONFIG_LZ4_COMPRESS) += lz4/ diff --git a/lib/bch.c b/lib/bch.c index bc89dfe4d1b3..07ee4f95d94c 100644 --- a/lib/bch.c +++ b/lib/bch.c @@ -78,15 +78,22 @@ #define GF_M(_p) (CONFIG_BCH_CONST_M) #define GF_T(_p) (CONFIG_BCH_CONST_T) #define GF_N(_p) ((1 << (CONFIG_BCH_CONST_M))-1) +#define BCH_MAX_M (CONFIG_BCH_CONST_M) #else #define GF_M(_p) ((_p)->m) #define GF_T(_p) ((_p)->t) #define GF_N(_p) ((_p)->n) +#define BCH_MAX_M 15 #endif +#define BCH_MAX_T (((1 << BCH_MAX_M) - 1) / BCH_MAX_M) + #define BCH_ECC_WORDS(_p) DIV_ROUND_UP(GF_M(_p)*GF_T(_p), 32) #define BCH_ECC_BYTES(_p) DIV_ROUND_UP(GF_M(_p)*GF_T(_p), 8) +#define BCH_ECC_MAX_WORDS DIV_ROUND_UP(BCH_MAX_M * BCH_MAX_T, 32) +#define BCH_ECC_MAX_BYTES DIV_ROUND_UP(BCH_MAX_M * BCH_MAX_T, 8) + #ifndef dbg #define dbg(_fmt, args...) do {} while (0) #endif @@ -187,7 +194,8 @@ void encode_bch(struct bch_control *bch, const uint8_t *data, const unsigned int l = BCH_ECC_WORDS(bch)-1; unsigned int i, mlen; unsigned long m; - uint32_t w, r[l+1]; + uint32_t w, r[BCH_ECC_MAX_WORDS]; + const size_t r_bytes = BCH_ECC_BYTES(bch); const uint32_t * const tab0 = bch->mod8_tab; const uint32_t * const tab1 = tab0 + 256*(l+1); const uint32_t * const tab2 = tab1 + 256*(l+1); @@ -198,7 +206,7 @@ void encode_bch(struct bch_control *bch, const uint8_t *data, /* load ecc parity bytes into internal 32-bit buffer */ load_ecc8(bch, bch->ecc_buf, ecc); } else { - memset(bch->ecc_buf, 0, sizeof(r)); + memset(bch->ecc_buf, 0, r_bytes); } /* process first unaligned data bytes */ @@ -215,7 +223,7 @@ void encode_bch(struct bch_control *bch, const uint8_t *data, mlen = len/4; data += 4*mlen; len -= 4*mlen; - memcpy(r, bch->ecc_buf, sizeof(r)); + memcpy(r, bch->ecc_buf, r_bytes); /* * split each 32-bit word into 4 polynomials of weight 8 as follows: @@ -241,7 +249,7 @@ void encode_bch(struct bch_control *bch, const uint8_t *data, r[l] = p0[l]^p1[l]^p2[l]^p3[l]; } - memcpy(bch->ecc_buf, r, sizeof(r)); + memcpy(bch->ecc_buf, r, r_bytes); /* process last unaligned bytes */ if (len) @@ -434,7 +442,7 @@ static int solve_linear_system(struct bch_control *bch, unsigned int *rows, { const int m = GF_M(bch); unsigned int tmp, mask; - int rem, c, r, p, k, param[m]; + int rem, c, r, p, k, param[BCH_MAX_M]; k = 0; mask = 1 << m; @@ -1114,7 +1122,7 @@ static int build_deg2_base(struct bch_control *bch) { const int m = GF_M(bch); int i, j, r; - unsigned int sum, x, y, remaining, ak = 0, xi[m]; + unsigned int sum, x, y, remaining, ak = 0, xi[BCH_MAX_M]; /* find k s.t. Tr(a^k) = 1 and 0 <= k < m */ for (i = 0; i < m; i++) { @@ -1254,7 +1262,6 @@ struct bch_control *init_bch(int m, int t, unsigned int prim_poly) struct bch_control *bch = NULL; const int min_m = 5; - const int max_m = 15; /* default primitive polynomials */ static const unsigned int prim_poly_tab[] = { @@ -1270,7 +1277,7 @@ struct bch_control *init_bch(int m, int t, unsigned int prim_poly) goto fail; } #endif - if ((m < min_m) || (m > max_m)) + if ((m < min_m) || (m > BCH_MAX_M)) /* * values of m greater than 15 are not currently supported; * supporting m > 15 would require changing table base type -- 2.17.0 -- Kees Cook Pixel Security