Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp2342450ybz; Thu, 23 Apr 2020 16:22:47 -0700 (PDT) X-Google-Smtp-Source: APiQypLu8oU6KbzyPAs+Plc7/zZUEacXraXqNBCqEpzqwCz0g+Wp5zUGYf20ZT3ngnGLPw0OfV6m X-Received: by 2002:aa7:cd7c:: with SMTP id ca28mr4919457edb.181.1587684167233; Thu, 23 Apr 2020 16:22:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587684167; cv=none; d=google.com; s=arc-20160816; b=pd2hRHhm5PGJi9Xs6VEVnHD7824/66izM/iQ607UZZ55dOi11M8VnCfeFEZrwXXrVV 28S2Xpi2ksB8cL0d3y+GVeiSSMQWkKgVUHtrEOCb3dn9Be4H8IOYtw20ud0AcusC5Vr0 9s4iedXBy6skMsKkRwkO0D51L5pqDwe8s7UECB0prHSgHVdDP98/4PD1NfDHlPTB8MiZ 8ED3mObdlsS2kLQiz+GowFWKo8T/zfCRIJM4eG9eiQPH+mqYOHHR4BfrtLlYGcsFdt20 LO81kzDgi+GijzST0KK+Ibk6V8cc3/rY2W0sHwV5+52yC7VSPYinx9269/QXXTqnV0ja XFVg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition; bh=RqCg6SF+vk/zWbDWo2BipMxTzUnjXtCP+13uvtSbrZw=; b=TspdfJ7Lwd6lpEp78Z6iDc2G6W2dUl0umgDyKzjvMl5n6AFpELbMHLbBXli/81NZ/W rxOexMC0mcMh/ggXkllcv1Hr8tnFt6qXUtfV7+hS07Ti3WoM6ZFwU0Mz35Y4CsiQO02P iCpBpfcuZ+10jPVGU9Pot3d3d0EJFdJM6JUvuowWjm9yReE06XuMTaUO0n+nQmPca44Q m9e0rn3SQjKdUZazQPwN1yF7aCqKZNhlxgke6fPS5LRhqzFZX2FU/wiM4UZDTf02jalV G5L+CRaWkkGboFoO9alIiBrNs8UKE2vz2uYzGF10Q9E+/qnxzh3ta5HcCWkvGsP2e0Q3 AYZQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d6si1877325edy.66.2020.04.23.16.22.24; Thu, 23 Apr 2020 16:22:47 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729895AbgDWXVE (ORCPT + 99 others); Thu, 23 Apr 2020 19:21:04 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:48548 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728203AbgDWXGd (ORCPT ); Thu, 23 Apr 2020 19:06:33 -0400 Received: from [192.168.4.242] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1jRkvL-0004bO-Dn; Fri, 24 Apr 2020 00:06:27 +0100 Received: from ben by deadeye with local (Exim 4.93) (envelope-from ) id 1jRkvJ-00E6iD-Ly; Fri, 24 Apr 2020 00:06:25 +0100 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, Denis Kirjanov , "Xu Wen" , "David Sterba" , "Greg Kroah-Hartman" , "Su Yue" , "Ben Hutchings" , "Qu Wenruo" Date: Fri, 24 Apr 2020 00:04:38 +0100 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) X-Patchwork-Hint: ignore Subject: [PATCH 3.16 051/245] btrfs: Check that each block group has corresponding chunk at mount time In-Reply-To: X-SA-Exim-Connect-IP: 192.168.4.242 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.83-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Qu Wenruo commit 514c7dca85a0bf40be984dab0b477403a6db901f upstream. A crafted btrfs image with incorrect chunk<->block group mapping will trigger a lot of unexpected things as the mapping is essential. Although the problem can be caught by block group item checker added in "btrfs: tree-checker: Verify block_group_item", it's still not sufficient. A sufficiently valid block group item can pass the check added by the mentioned patch but could fail to match the existing chunk. This patch will add extra block group -> chunk mapping check, to ensure we have a completely matching (start, len, flags) chunk for each block group at mount time. Here we reuse the original helper find_first_block_group(), which is already doing the basic bg -> chunk checks, adding further checks of the start/len and type flags. Link: https://bugzilla.kernel.org/show_bug.cgi?id=199837 Reported-by: Xu Wen Signed-off-by: Qu Wenruo Reviewed-by: Su Yue Reviewed-by: David Sterba Signed-off-by: David Sterba [bwh: Backported to 4.4: Use root->fs_info instead of fs_info] Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman Signed-off-by: Ben Hutchings --- fs/btrfs/extent-tree.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -8556,6 +8556,8 @@ static int find_first_block_group(struct int ret = 0; struct btrfs_key found_key; struct extent_buffer *leaf; + struct btrfs_block_group_item bg; + u64 flags; int slot; ret = btrfs_search_slot(NULL, root, key, path, 0, 0); @@ -8590,8 +8592,32 @@ static int find_first_block_group(struct "logical %llu len %llu found bg but no related chunk", found_key.objectid, found_key.offset); ret = -ENOENT; + } else if (em->start != found_key.objectid || + em->len != found_key.offset) { + btrfs_err(root->fs_info, + "block group %llu len %llu mismatch with chunk %llu len %llu", + found_key.objectid, found_key.offset, + em->start, em->len); + ret = -EUCLEAN; } else { - ret = 0; + read_extent_buffer(leaf, &bg, + btrfs_item_ptr_offset(leaf, slot), + sizeof(bg)); + flags = btrfs_block_group_flags(&bg) & + BTRFS_BLOCK_GROUP_TYPE_MASK; + + if (flags != (em->map_lookup->type & + BTRFS_BLOCK_GROUP_TYPE_MASK)) { + btrfs_err(root->fs_info, +"block group %llu len %llu type flags 0x%llx mismatch with chunk type flags 0x%llx", + found_key.objectid, + found_key.offset, flags, + (BTRFS_BLOCK_GROUP_TYPE_MASK & + em->map_lookup->type)); + ret = -EUCLEAN; + } else { + ret = 0; + } } free_extent_map(em); goto out;