From patchwork Tue May 29 23:44:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kees Cook X-Patchwork-Id: 10437397 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8DBAD601C7 for ; Tue, 29 May 2018 23:45:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7CE2427F3E for ; Tue, 29 May 2018 23:45:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7167428806; Tue, 29 May 2018 23:45:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 141C827F3E for ; Tue, 29 May 2018 23:45:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755113AbeE2XpD (ORCPT ); Tue, 29 May 2018 19:45:03 -0400 Received: from mail-pf0-f194.google.com ([209.85.192.194]:44266 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754671AbeE2XpB (ORCPT ); Tue, 29 May 2018 19:45:01 -0400 Received: by mail-pf0-f194.google.com with SMTP id q22-v6so8033631pff.11 for ; Tue, 29 May 2018 16:45:01 -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; bh=6Ee+6FtpS3uLGJZrDK8+8a+WzIsnxcd6JMEZAXOGAG0=; b=NsU86s0eqEV9VPAC4cq5MhmkJ4mDC1t5j166S4coj5r/f4TPAYDxPicIm7CIWyWq1x j/tV+oiCMLH3yU4MlRkmQo6GHwBexbyu+AHWHycLxQ7Hy5n9+QD+pv/f7joNZkXWQj/c aZy+Wox0IQaecUU/TewtvYU6jmaPhZb6Bp/qw= 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; bh=6Ee+6FtpS3uLGJZrDK8+8a+WzIsnxcd6JMEZAXOGAG0=; b=b88iJTIrTUlIZr3WDXl13Hlm0dQ6PAe97xq/uds7GZ020fTF1YRW8rrZq0J+/U6Bpz GE8ofTuixz4CMbhJMg8h8ry22dgOsyZuLGr/thvWhDvzays7rL9IRrgDmGjCl7rj9kwS K/JQiXMoP1nCOSy0tX8nsqtFO8VUGUV8NpHTIpPHFliwok3RKFExvhGwZGWJytvReH3E zd88X48ZOJx32qCVlARU2FOv9MsBtKOCQIpS6h1PMxickrDScV+JvOo/KLBVbNSXQqom kyyFoWiua1kN5wFqguFFdEt0YwWJmO0Tv+MjVDgkmcLZ8qNpOX4cuZpabVZOFIt/pKTE kS0g== X-Gm-Message-State: ALKqPwd2HNnpiLM8JUgmCNX9RTDnsEJYmV0cNhyUiqr/ZKpqaQyoCbhu 2ydtbP6TU0AaLM/WOEM2YtZJqg== X-Google-Smtp-Source: ADUXVKLuvhdGyW/Ptdx2GWLYAvkisK8S+SRRQMrRZHTIq/XAWjhSfvmqpuJpxPv2meY3drOTrJ5DWA== X-Received: by 2002:a65:4ac3:: with SMTP id c3-v6mr333824pgu.329.1527637501257; Tue, 29 May 2018 16:45:01 -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 t24-v6sm68403356pfj.75.2018.05.29.16.44.59 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 29 May 2018 16:45:00 -0700 (PDT) Date: Tue, 29 May 2018 16:44:59 -0700 From: Kees Cook To: David Sterba Cc: Liu Bo , Chris Mason , Josef Bacik , linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] btrfs: raid56: Remove VLA usage Message-ID: <20180529234459.GA15302@beast> MIME-Version: 1.0 Content-Disposition: inline Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP In the quest to remove all stack VLA usage from the kernel[1], this allocates the working buffers during regular init, instead of using stack space. This refactors the allocation code a bit to make it easier to review. [1] https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qPXydAacU1RqZWA@mail.gmail.com Signed-off-by: Kees Cook Reviewed-by: David Sterba --- fs/btrfs/raid56.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index 9abd950e7f78..5e4ad134b9ad 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c @@ -163,6 +163,12 @@ struct btrfs_raid_bio { * bitmap to record which horizontal stripe has data */ unsigned long *dbitmap; + + /* allocated with real_stripes-many pointers for finish_*() calls */ + void **finish_pointers; + + /* allocated with stripe_npages-many bits for finish_*() calls */ + unsigned long *finish_pbitmap; }; static int __raid56_parity_recover(struct btrfs_raid_bio *rbio); @@ -981,9 +987,14 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info, int stripe_npages = DIV_ROUND_UP(stripe_len, PAGE_SIZE); void *p; - rbio = kzalloc(sizeof(*rbio) + num_pages * sizeof(struct page *) * 2 + - DIV_ROUND_UP(stripe_npages, BITS_PER_LONG) * - sizeof(long), GFP_NOFS); + rbio = kzalloc(sizeof(*rbio) + + sizeof(*rbio->stripe_pages) * num_pages + + sizeof(*rbio->bio_pages) * num_pages + + sizeof(*rbio->finish_pointers) * real_stripes + + sizeof(*rbio->dbitmap) * BITS_TO_LONGS(stripe_npages) + + sizeof(*rbio->finish_pbitmap) * + BITS_TO_LONGS(stripe_npages), + GFP_NOFS); if (!rbio) return ERR_PTR(-ENOMEM); @@ -1005,13 +1016,20 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info, atomic_set(&rbio->stripes_pending, 0); /* - * the stripe_pages and bio_pages array point to the extra + * the stripe_pages, bio_pages, etc arrays point to the extra * memory we allocated past the end of the rbio */ p = rbio + 1; - rbio->stripe_pages = p; - rbio->bio_pages = p + sizeof(struct page *) * num_pages; - rbio->dbitmap = p + sizeof(struct page *) * num_pages * 2; +#define CONSUME_ALLOC(ptr, count) do { \ + ptr = p; \ + p = (unsigned char *)p + sizeof(*(ptr)) * (count); \ + } while (0) + CONSUME_ALLOC(rbio->stripe_pages, num_pages); + CONSUME_ALLOC(rbio->bio_pages, num_pages); + CONSUME_ALLOC(rbio->finish_pointers, real_stripes); + CONSUME_ALLOC(rbio->dbitmap, BITS_TO_LONGS(stripe_npages)); + CONSUME_ALLOC(rbio->finish_pbitmap, BITS_TO_LONGS(stripe_npages)); +#undef CONSUME_ALLOC if (bbio->map_type & BTRFS_BLOCK_GROUP_RAID5) nr_data = real_stripes - 1; @@ -1180,7 +1198,7 @@ static void index_rbio_pages(struct btrfs_raid_bio *rbio) static noinline void finish_rmw(struct btrfs_raid_bio *rbio) { struct btrfs_bio *bbio = rbio->bbio; - void *pointers[rbio->real_stripes]; + void **pointers = rbio->finish_pointers; int nr_data = rbio->nr_data; int stripe; int pagenr; @@ -2350,8 +2368,8 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, int need_check) { struct btrfs_bio *bbio = rbio->bbio; - void *pointers[rbio->real_stripes]; - DECLARE_BITMAP(pbitmap, rbio->stripe_npages); + void **pointers = rbio->finish_pointers; + unsigned long *pbitmap = rbio->finish_pbitmap; int nr_data = rbio->nr_data; int stripe; int pagenr;