From patchwork Thu May 31 18:45:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 923542 X-Patchwork-Delegate: boris.brezillon@free-electrons.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="t73fz8Pm"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="lMUmnu19"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40xbyL50QYz9s0W for ; Fri, 1 Jun 2018 04:46:00 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Subject:To:From :Date:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=GuXF5wxR/BOh1AFYDg+KpyOsn8LiRXnCi4XT+bXW7F0=; b=t73fz8PmpmIsyf D1n1yboVkypLIQE3dX2onUETJDYmRlGB0FsBAQHdqiCF7ik3wnFJDUkWMBxZkwzcMWSlIHODxPUyf 0YMrD2kqCMPqSJADwGVf5ZkDdf4ekUV+In5vcr22V/ERWcf9jaZymLfFdgiV39/ZuJB6Xgyfpa/MZ O678sdogvrWa89FRJhXCAyo9ZHTwl6oeadF7/jUo9G//UMLfBR1NOwC69ie054KcstfJbbQgYr/0Y 05MPlp9r3aT0RhT3uflvJNCMOGYBd4+jjtoXQFSjtncVf6gCR0zAbWJjx+gbVz6UMpiT7i9FOLcd4 CDpDIM4Sztja/XO4a8yw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fOSa3-0002fz-Hn; Thu, 31 May 2018 18:45:47 +0000 Received: from mail-pl0-x244.google.com ([2607:f8b0:400e:c01::244]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fOSZx-0002eI-As for linux-mtd@lists.infradead.org; Thu, 31 May 2018 18:45:45 +0000 Received: by mail-pl0-x244.google.com with SMTP id 30-v6so13725436pld.13 for ; Thu, 31 May 2018 11:45:28 -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=hnQPO58auPllKLLHqB8Pi3sS2xq8AhiS7k+lIg6hzIA=; b=lMUmnu19d2ytCX0Lil0yUsrQr3KNcM/qQJBvPO6/M5gZtzlPX018t0SNWoP65Q/tGY JOigX71+wUdQ6oikv4gSnVc98tzYJSvHor3UE8slFng0SGzhK0lFukECQAN2XMVEcCCG nEtINx+WejW9jOpSWhnhlG7EBq7cfd8eA7B3o= 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=hnQPO58auPllKLLHqB8Pi3sS2xq8AhiS7k+lIg6hzIA=; b=X2l6xOdeDM8bXbxb4ziDc56hy1H9R0sBNxE2Ajq9my/qgN6DApYv7V/qaqolOCkLPA wkjcoG8ZFhCLTSjR9QHqtakDPIA6ypn3N/WZndt3xBam0LesGzytMosg161+YQnbgYkx YrbZP5a5pAZYS3UHhsBo+xMYXKYixm6mg8Hyq+eS2yHbo2mh3PHE4Q4IY1MY0HsZu14E J7H7ounSwVgP31EJGxJkTuVAf4X5Rg5H60paJ0kK2WkPyRVAuotUucld98TFE0sTjVXk 5ueRrmRQyfbBKgF2f5GAK9FNxsM/aUNZDPElZMj6Jg4XXxaBQN3QClwZS+z2kzGdm6du zkNA== X-Gm-Message-State: ALKqPwdCx9QMfGuQGfVxhvZ5rjaOetEMmePUU5SCHPW9NPzbzp5QO1Jb zP5BWEHudTClEUyMKBhbPK2i9Q== X-Google-Smtp-Source: ADUXVKJ0UxoUxbVPzQ8W9c6BJZk7d0zVfl2sV1aEQYLa+7naNj2jyNb1Usr/Y2e5DCtaW8sRByoEJQ== X-Received: by 2002:a17:902:7598:: with SMTP id j24-v6mr8049626pll.160.1527792328022; Thu, 31 May 2018 11:45:28 -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 29-v6sm15488798pfp.24.2018.05.31.11.45.25 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 31 May 2018 11:45:26 -0700 (PDT) Date: Thu, 31 May 2018 11:45:25 -0700 From: Kees Cook To: Ivan Djelic Subject: [PATCH v3] lib/bch: Remove VLA usage Message-ID: <20180531184525.GA11068@beast> MIME-Version: 1.0 Content-Disposition: inline X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180531_114541_383560_08A07854 X-CRM114-Status: GOOD ( 19.37 ) X-Spam-Score: -0.1 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-0.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [2607:f8b0:400e:c01:0:0:0:244 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marek Vasut , Richard Weinberger , LKML , Boris Brezillon , Linux mtd , Brian Norris , David Woodhouse Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.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 Reviewed-by: Ivan Djelic Tested-by: Ivan Djelic Acked-by: Boris Brezillon --- v3: fix r_bytes to whole-word size 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..7b0f2006698b 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_WORDS(bch) * sizeof(*r); 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