Received: by 2002:ad5:4acb:0:0:0:0:0 with SMTP id n11csp1239001imw; Tue, 5 Jul 2022 06:15:40 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sxZvmNNiR8NMY5UT+sX3XQs2lyH2trj47zrM5/9Nkow8LpFaIoiAl0wYUAwaiqLRBNStkx X-Received: by 2002:a17:90b:3845:b0:1ec:c4a3:22be with SMTP id nl5-20020a17090b384500b001ecc4a322bemr41348437pjb.137.1657026939694; Tue, 05 Jul 2022 06:15:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657026939; cv=none; d=google.com; s=arc-20160816; b=NrVbhfQzJwDcP1/2Qun+6On1xJOQBDdT1iQXSbfWVqGyu0cIRWJUsQpWBvdtQruSiH uX7+Y9oF57T2BERn0SqpfXz0M2hIbEPnIKy8wepEhH5iCG4K1iYM89ieTL5UOj8aobJ6 aka5Xkna8/VlzYsqeEt1IXtz10ryrz5q2E+EuqhR6mphs3+QueDZn5Bj5G3VdujSR2rN sJjSX3/NK9eIjuAKl2VObCV4NV7bgkRzaZSFwbRYnLuFq3fP2/6egW3cF25fcsAcDxFh I8K5ySssY6ek8CCEh9xuIdt1FRCIKEWqV9u4fE7Zs+ifuptj0LrhJ1FL5d5KNHT4Awmh XXIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=xSZo8lN92zaxtZ5NiFAbwpX1H9CCqsWdZmRhz4DttgQ=; b=Of7r7LxXvE5JN2I1irenX4/HJRWkVHr/blypM0uXxans6yXiRAzOzb4cJfDjjWbiyY SHERCidItf2oWMS0OcnSMqJcD3xfMp4T6kXMNy1dRxrUHqt+1Bpv1TYrid1z3GwOEwcU SlVzmySM2ss1iDuvp6cUEJtXRIkZ94R125eLRuucHkxWFi1NU5X+KeZLjI+cfzRkornT xHUxlQHp/wmdGgIR7S2JfhT9YMBCezICaJXACQXFNzJxNqjhQ7rbo6WJM9/YBHLyiqks e6mszzmdioiwqhB/piCeoLEWnq7B8awVHdN3ZUoH3pU3boZfDH5qES53e+xEAzpdJbjX Z+rA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=tQvn60ib; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b11-20020a17090ae38b00b001ef9fa82c2fsi1415153pjz.186.2022.07.05.06.15.28; Tue, 05 Jul 2022 06:15:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=tQvn60ib; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233374AbiGEMEq (ORCPT + 99 others); Tue, 5 Jul 2022 08:04:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233416AbiGEMCl (ORCPT ); Tue, 5 Jul 2022 08:02:41 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C252D17AA6; Tue, 5 Jul 2022 05:02:39 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 7FCFEB817D2; Tue, 5 Jul 2022 12:02:38 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E7C09C341C7; Tue, 5 Jul 2022 12:02:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1657022557; bh=i/hkVa2NdrzKB2U6labkeByD8GX4/FsFhvltr0Zeq0s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tQvn60ibf15v1jtBNl7Hc//SdxsRq3IPYlUvV5X9jUyAYAGRquH8fD4+nrkOzZQgB byZTLJXfa6+Mv9N93OSlYLJkh6LZVNvLw60erM5s/2UXtJRtq9z/syXXV+lSC4I0br V2l+ZEN9vzvm53Wmz2Xn902QSPGlZSWpF5zwlAmg= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Heinz Mauelshagen , Mike Snitzer Subject: [PATCH 4.19 02/33] dm raid: fix accesses beyond end of raid member array Date: Tue, 5 Jul 2022 13:57:54 +0200 Message-Id: <20220705115606.782705842@linuxfoundation.org> X-Mailer: git-send-email 2.37.0 In-Reply-To: <20220705115606.709817198@linuxfoundation.org> References: <20220705115606.709817198@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Heinz Mauelshagen commit 332bd0778775d0cf105c4b9e03e460b590749916 upstream. On dm-raid table load (using raid_ctr), dm-raid allocates an array rs->devs[rs->raid_disks] for the raid device members. rs->raid_disks is defined by the number of raid metadata and image tupples passed into the target's constructor. In the case of RAID layout changes being requested, that number can be different from the current number of members for existing raid sets as defined in their superblocks. Example RAID layout changes include: - raid1 legs being added/removed - raid4/5/6/10 number of stripes changed (stripe reshaping) - takeover to higher raid level (e.g. raid5 -> raid6) When accessing array members, rs->raid_disks must be used in control loops instead of the potentially larger value in rs->md.raid_disks. Otherwise it will cause memory access beyond the end of the rs->devs array. Fix this by changing code that is prone to out-of-bounds access. Also fix validate_raid_redundancy() to validate all devices that are added. Also, use braces to help clean up raid_iterate_devices(). The out-of-bounds memory accesses was discovered using KASAN. This commit was verified to pass all LVM2 RAID tests (with KASAN enabled). Cc: stable@vger.kernel.org Signed-off-by: Heinz Mauelshagen Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-raid.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -998,12 +998,13 @@ static int validate_region_size(struct r static int validate_raid_redundancy(struct raid_set *rs) { unsigned int i, rebuild_cnt = 0; - unsigned int rebuilds_per_group = 0, copies; + unsigned int rebuilds_per_group = 0, copies, raid_disks; unsigned int group_size, last_group_start; - for (i = 0; i < rs->md.raid_disks; i++) - if (!test_bit(In_sync, &rs->dev[i].rdev.flags) || - !rs->dev[i].rdev.sb_page) + for (i = 0; i < rs->raid_disks; i++) + if (!test_bit(FirstUse, &rs->dev[i].rdev.flags) && + ((!test_bit(In_sync, &rs->dev[i].rdev.flags) || + !rs->dev[i].rdev.sb_page))) rebuild_cnt++; switch (rs->md.level) { @@ -1043,8 +1044,9 @@ static int validate_raid_redundancy(stru * A A B B C * C D D E E */ + raid_disks = min(rs->raid_disks, rs->md.raid_disks); if (__is_raid10_near(rs->md.new_layout)) { - for (i = 0; i < rs->md.raid_disks; i++) { + for (i = 0; i < raid_disks; i++) { if (!(i % copies)) rebuilds_per_group = 0; if ((!rs->dev[i].rdev.sb_page || @@ -1067,10 +1069,10 @@ static int validate_raid_redundancy(stru * results in the need to treat the last (potentially larger) * set differently. */ - group_size = (rs->md.raid_disks / copies); - last_group_start = (rs->md.raid_disks / group_size) - 1; + group_size = (raid_disks / copies); + last_group_start = (raid_disks / group_size) - 1; last_group_start *= group_size; - for (i = 0; i < rs->md.raid_disks; i++) { + for (i = 0; i < raid_disks; i++) { if (!(i % copies) && !(i > last_group_start)) rebuilds_per_group = 0; if ((!rs->dev[i].rdev.sb_page || @@ -1585,7 +1587,7 @@ static sector_t __rdev_sectors(struct ra { int i; - for (i = 0; i < rs->md.raid_disks; i++) { + for (i = 0; i < rs->raid_disks; i++) { struct md_rdev *rdev = &rs->dev[i].rdev; if (!test_bit(Journal, &rdev->flags) && @@ -3751,13 +3753,13 @@ static int raid_iterate_devices(struct d unsigned int i; int r = 0; - for (i = 0; !r && i < rs->md.raid_disks; i++) - if (rs->dev[i].data_dev) - r = fn(ti, - rs->dev[i].data_dev, - 0, /* No offset on data devs */ - rs->md.dev_sectors, - data); + for (i = 0; !r && i < rs->raid_disks; i++) { + if (rs->dev[i].data_dev) { + r = fn(ti, rs->dev[i].data_dev, + 0, /* No offset on data devs */ + rs->md.dev_sectors, data); + } + } return r; }