From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1l0jNR-0000Et-7I for mharc-grub-devel@gnu.org; Sat, 16 Jan 2021 06:04:18 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:33872) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l0jNM-0000E9-6t for grub-devel@gnu.org; Sat, 16 Jan 2021 06:04:15 -0500 Received: from mta.outflux.net ([2001:19d0:2:6:c0de:0:736d:7471]:53431 helo=smtp.outflux.net) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l0jNJ-0002Lt-Rj for grub-devel@gnu.org; Sat, 16 Jan 2021 06:04:11 -0500 Received: from www.outflux.net (serenity.outflux.net [10.2.0.2]) by vinyl.outflux.net (8.15.2/8.15.2/Debian-10) with ESMTP id 10GB46sg015397 for ; Sat, 16 Jan 2021 03:04:06 -0800 Received: by www.outflux.net (Postfix, from userid 501) id D49F36054E; Sat, 16 Jan 2021 03:04:05 -0800 (PST) Date: Sat, 16 Jan 2021 03:04:05 -0800 From: Kees Cook To: grub-devel@gnu.org Subject: [PATCH] Fix potential truncation of mdraid device list Message-ID: <20210116110405.GA4996@outflux.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Organization: Outflux X-MIMEDefang-Filter: outflux$Revision: 1.316 $ X-HELO: www.outflux.net X-Scanned-By: MIMEDefang 2.83 Received-SPF: none client-ip=2001:19d0:2:6:c0de:0:736d:7471; envelope-from=kees@ubuntu.com; helo=smtp.outflux.net X-Spam_score_int: -4 X-Spam_score: -0.5 X-Spam_bar: / X-Spam_report: (-0.5 / 5.0 requ) BAYES_00=-1.9, FORGED_SPF_HELO=1, KHOP_HELO_FCRDNS=0.399, SPF_HELO_PASS=-0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Jan 2021 11:04:16 -0000 The consumer of grub_util_raid_getmembers() expects a NULL terminated list of device names. It has no idea about how many devices are registered in the array; it only cares about active devices. As a result, there cannot be gaps in the list, otherwise the first listed inactive device will cause all remaining devices to effectively vanish. This is especially troublesome if a root filesystem were on an array with the first device being a hot spare: the array would appear to have no disks and the root filesystem would become invisible to grub. Fixes: 49de079bbe1c ("... (grub_util_raid_getmembers): Handle "removed" disks") Fixes: https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1912043 Fixes: https://savannah.gnu.org/bugs/index.php?59887 Signed-off-by: Kees Cook Index: grub2-2.04/grub-core/osdep/linux/getroot.c =================================================================== --- grub2-2.04.orig/grub-core/osdep/linux/getroot.c +++ grub2-2.04/grub-core/osdep/linux/getroot.c @@ -170,21 +170,21 @@ grub_util_raid_getmembers (const char *n devicelist = xcalloc (info.nr_disks + 1, sizeof (char *)); - for (i = 0, j = 0; j < info.nr_disks; i++) + for (i = 0, j = 0; i < info.nr_disks; i++) { disk.number = i; ret = ioctl (fd, GET_DISK_INFO, &disk); if (ret != 0) grub_util_error (_("ioctl GET_DISK_INFO error: %s"), strerror (errno)); - + if (disk.state & (1 << MD_DISK_REMOVED)) continue; - if (disk.state & (1 << MD_DISK_ACTIVE)) - devicelist[j] = grub_find_device (NULL, - makedev (disk.major, disk.minor)); - else - devicelist[j] = NULL; + if (!(disk.state & (1 << MD_DISK_ACTIVE))) + continue; + + devicelist[j] = grub_find_device (NULL, + makedev (disk.major, disk.minor)); j++; } -- Kees Cook @outflux.net