nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

Blame SOURCES/0447-fs-nilfs2-Don-t-search-children-if-provided-number-i.patch

9723a8
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
9723a8
From: Daniel Axtens <dja@axtens.net>
9723a8
Date: Mon, 18 Jan 2021 16:49:44 +1100
9723a8
Subject: [PATCH] fs/nilfs2: Don't search children if provided number is too
9723a8
 large
9723a8
9723a8
NILFS2 reads the number of children a node has from the node. Unfortunately,
9723a8
that's not trustworthy. Check if it's beyond what the filesystem permits and
9723a8
reject it if so.
9723a8
9723a8
This blocks some OOB reads. I'm not sure how controllable the read is and what
9723a8
could be done with invalidly read data later on.
9723a8
9723a8
Signed-off-by: Daniel Axtens <dja@axtens.net>
9723a8
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
9723a8
---
9723a8
 grub-core/fs/nilfs2.c | 38 +++++++++++++++++++++++---------------
9723a8
 1 file changed, 23 insertions(+), 15 deletions(-)
9723a8
9723a8
diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c
9723a8
index 61e8af9ff7b..054ad3dc18a 100644
9723a8
--- a/grub-core/fs/nilfs2.c
9723a8
+++ b/grub-core/fs/nilfs2.c
9723a8
@@ -416,14 +416,34 @@ grub_nilfs2_btree_node_get_key (struct grub_nilfs2_btree_node *node,
9723a8
 }
9723a8
 
9723a8
 static inline int
9723a8
-grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node,
9723a8
+grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data,
9723a8
+				      struct grub_nilfs2_btree_node *node)
9723a8
+{
9723a8
+  int node_children_max = ((NILFS2_BLOCK_SIZE (data) -
9723a8
+			    sizeof (struct grub_nilfs2_btree_node) -
9723a8
+			    NILFS_BTREE_NODE_EXTRA_PAD_SIZE) /
9723a8
+			   (sizeof (grub_uint64_t) + sizeof (grub_uint64_t)));
9723a8
+
9723a8
+  return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max;
9723a8
+}
9723a8
+
9723a8
+static inline int
9723a8
+grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data,
9723a8
+			       struct grub_nilfs2_btree_node *node,
9723a8
 			       grub_uint64_t key, int *indexp)
9723a8
 {
9723a8
   grub_uint64_t nkey;
9723a8
   int index, low, high, s;
9723a8
 
9723a8
   low = 0;
9723a8
+
9723a8
   high = grub_le_to_cpu16 (node->bn_nchildren) - 1;
9723a8
+  if (high >= grub_nilfs2_btree_node_nchildren_max (data, node))
9723a8
+    {
9723a8
+      grub_error (GRUB_ERR_BAD_FS, "too many children");
9723a8
+      return 0;
9723a8
+    }
9723a8
+
9723a8
   index = 0;
9723a8
   s = 0;
9723a8
   while (low <= high)
9723a8
@@ -459,18 +479,6 @@ grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node,
9723a8
   return s == 0;
9723a8
 }
9723a8
 
9723a8
-static inline int
9723a8
-grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data,
9723a8
-				      struct grub_nilfs2_btree_node *node)
9723a8
-{
9723a8
-  int node_children_max = ((NILFS2_BLOCK_SIZE (data) -
9723a8
-			    sizeof (struct grub_nilfs2_btree_node) -
9723a8
-			    NILFS_BTREE_NODE_EXTRA_PAD_SIZE) /
9723a8
-			   (sizeof (grub_uint64_t) + sizeof (grub_uint64_t)));
9723a8
-
9723a8
-  return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max;
9723a8
-}
9723a8
-
9723a8
 static inline grub_uint64_t *
9723a8
 grub_nilfs2_btree_node_dptrs (struct grub_nilfs2_data *data,
9723a8
 			      struct grub_nilfs2_btree_node *node)
9723a8
@@ -517,7 +525,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
9723a8
   node = grub_nilfs2_btree_get_root (inode);
9723a8
   level = grub_nilfs2_btree_get_level (node);
9723a8
 
9723a8
-  found = grub_nilfs2_btree_node_lookup (node, key, &index);
9723a8
+  found = grub_nilfs2_btree_node_lookup (data, node, key, &index);
9723a8
   ptr = grub_nilfs2_btree_node_get_ptr (data, node, index);
9723a8
   if (need_translate)
9723a8
     ptr = grub_nilfs2_dat_translate (data, ptr);
9723a8
@@ -538,7 +546,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
9723a8
 	}
9723a8
 
9723a8
       if (!found)
9723a8
-	found = grub_nilfs2_btree_node_lookup (node, key, &index);
9723a8
+	found = grub_nilfs2_btree_node_lookup (data, node, key, &index);
9723a8
       else
9723a8
 	index = 0;
9723a8