]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Mon, 15 Jun 2020 03:27:39 +0000 (23:27 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 15 Jun 2020 03:27:39 +0000 (23:27 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.19/btrfs-tree-checker-check-level-for-leaves-and-nodes.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/btrfs-tree-checker-check-level-for-leaves-and-nodes.patch b/queue-4.19/btrfs-tree-checker-check-level-for-leaves-and-nodes.patch
new file mode 100644 (file)
index 0000000..938c68d
--- /dev/null
@@ -0,0 +1,64 @@
+From 8f77ba4ef3fe576ee26236469647056d88874af5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Sep 2018 07:59:34 +0800
+Subject: btrfs: tree-checker: Check level for leaves and nodes
+
+From: Qu Wenruo <wqu@suse.com>
+
+[ Upstream commit f556faa46eb4e96d0d0772e74ecf66781e132f72 ]
+
+Although we have tree level check at tree read runtime, it's completely
+based on its parent level.
+We still need to do accurate level check to avoid invalid tree blocks
+sneak into kernel space.
+
+The check itself is simple, for leaf its level should always be 0.
+For nodes its level should be in range [1, BTRFS_MAX_LEVEL - 1].
+
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Reviewed-by: Su Yue <suy.fnst@cn.fujitsu.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/tree-checker.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
+index 235c2970b944..d98ec885b72a 100644
+--- a/fs/btrfs/tree-checker.c
++++ b/fs/btrfs/tree-checker.c
+@@ -485,6 +485,13 @@ static int check_leaf(struct btrfs_fs_info *fs_info, struct extent_buffer *leaf,
+       u32 nritems = btrfs_header_nritems(leaf);
+       int slot;
++      if (btrfs_header_level(leaf) != 0) {
++              generic_err(fs_info, leaf, 0,
++                      "invalid level for leaf, have %d expect 0",
++                      btrfs_header_level(leaf));
++              return -EUCLEAN;
++      }
++
+       /*
+        * Extent buffers from a relocation tree have a owner field that
+        * corresponds to the subvolume tree they are based on. So just from an
+@@ -649,9 +656,16 @@ int btrfs_check_node(struct btrfs_fs_info *fs_info, struct extent_buffer *node)
+       unsigned long nr = btrfs_header_nritems(node);
+       struct btrfs_key key, next_key;
+       int slot;
++      int level = btrfs_header_level(node);
+       u64 bytenr;
+       int ret = 0;
++      if (level <= 0 || level >= BTRFS_MAX_LEVEL) {
++              generic_err(fs_info, node, 0,
++                      "invalid level for node, have %d expect [1, %d]",
++                      level, BTRFS_MAX_LEVEL - 1);
++              return -EUCLEAN;
++      }
+       if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(fs_info)) {
+               btrfs_crit(fs_info,
+ "corrupt node: root=%llu block=%llu, nritems too %s, have %lu expect range [1,%u]",
+-- 
+2.25.1
+
index ad06d9fa8fc30240fb750455688c2ced51e4283b..eb04d3c102c98b3d7dae612742ea68973e600fcd 100644 (file)
@@ -23,3 +23,4 @@ rdma-uverbs-make-the-event_queue-fds-return-pollerr-.patch
 x86-cpu-amd-make-erratum-1054-a-legacy-erratum.patch
 perf-probe-accept-the-instance-number-of-kretprobe-e.patch
 mm-add-kvfree_sensitive-for-freeing-sensitive-data-o.patch
+btrfs-tree-checker-check-level-for-leaves-and-nodes.patch