[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[SECURITY PATCH 080/117] fs/nilfs2: Don't search children if provided nu
From: |
Daniel Kiper |
Subject: |
[SECURITY PATCH 080/117] fs/nilfs2: Don't search children if provided number is too large |
Date: |
Tue, 2 Mar 2021 19:01:27 +0100 |
From: Daniel Axtens <dja@axtens.net>
NILFS2 reads the number of children a node has from the node. Unfortunately,
that's not trustworthy. Check if it's beyond what the filesystem permits and
reject it if so.
This blocks some OOB reads. I'm not sure how controllable the read is and what
could be done with invalidly read data later on.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/nilfs2.c | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c
index 20053caf5..7963b4ef5 100644
--- a/grub-core/fs/nilfs2.c
+++ b/grub-core/fs/nilfs2.c
@@ -416,14 +416,34 @@ grub_nilfs2_btree_node_get_key (struct
grub_nilfs2_btree_node *node,
}
static inline int
-grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node,
+grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data,
+ struct grub_nilfs2_btree_node *node)
+{
+ int node_children_max = ((NILFS2_BLOCK_SIZE (data) -
+ sizeof (struct grub_nilfs2_btree_node) -
+ NILFS_BTREE_NODE_EXTRA_PAD_SIZE) /
+ (sizeof (grub_uint64_t) + sizeof (grub_uint64_t)));
+
+ return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max;
+}
+
+static inline int
+grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data,
+ struct grub_nilfs2_btree_node *node,
grub_uint64_t key, int *indexp)
{
grub_uint64_t nkey;
int index, low, high, s;
low = 0;
+
high = grub_le_to_cpu16 (node->bn_nchildren) - 1;
+ if (high >= grub_nilfs2_btree_node_nchildren_max (data, node))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "too many children");
+ return 0;
+ }
+
index = 0;
s = 0;
while (low <= high)
@@ -459,18 +479,6 @@ grub_nilfs2_btree_node_lookup (struct
grub_nilfs2_btree_node *node,
return s == 0;
}
-static inline int
-grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data,
- struct grub_nilfs2_btree_node *node)
-{
- int node_children_max = ((NILFS2_BLOCK_SIZE (data) -
- sizeof (struct grub_nilfs2_btree_node) -
- NILFS_BTREE_NODE_EXTRA_PAD_SIZE) /
- (sizeof (grub_uint64_t) + sizeof (grub_uint64_t)));
-
- return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max;
-}
-
static inline grub_uint64_t *
grub_nilfs2_btree_node_dptrs (struct grub_nilfs2_data *data,
struct grub_nilfs2_btree_node *node)
@@ -517,7 +525,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
node = grub_nilfs2_btree_get_root (inode);
level = grub_nilfs2_btree_get_level (node);
- found = grub_nilfs2_btree_node_lookup (node, key, &index);
+ found = grub_nilfs2_btree_node_lookup (data, node, key, &index);
ptr = grub_nilfs2_btree_node_get_ptr (data, node, index);
if (need_translate)
ptr = grub_nilfs2_dat_translate (data, ptr);
@@ -538,7 +546,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
}
if (!found)
- found = grub_nilfs2_btree_node_lookup (node, key, &index);
+ found = grub_nilfs2_btree_node_lookup (data, node, key, &index);
else
index = 0;
--
2.11.0
- [SECURITY PATCH 079/117] fs/nilfs2: Reject too-large keys, (continued)
- [SECURITY PATCH 079/117] fs/nilfs2: Reject too-large keys, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 077/117] fs/jfs: Limit the extents that getblk() can consider, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 084/117] io/gzio: Catch missing values in huft_build() and bail, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 086/117] disk/lvm: Don't go beyond the end of the data we read from disk, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 087/117] disk/lvm: Don't blast past the end of the circular metadata buffer, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 089/117] disk/lvm: Do not crash if an expected string is not found, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 085/117] io/gzio: Zero gzio->tl/td in init_dynamic_block() if huft_build() fails, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 091/117] disk/lvm: Sanitize rlocn->offset to prevent wild read, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 096/117] kern/parser: Introduce process_char() helper, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 097/117] kern/parser: Introduce terminate_arg() helper, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 080/117] fs/nilfs2: Don't search children if provided number is too large,
Daniel Kiper <=
- [SECURITY PATCH 088/117] disk/lvm: Bail on missing PV list, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 099/117] kern/buffer: Add variable sized heap buffer, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 076/117] fs/jfs: Do not move to leaf level if name length is negative, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 075/117] fs/sfs: Fix over-read of root object name, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 074/117] fs/hfs: Disable under lockdown, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 094/117] fs/btrfs: Squash some uninitialized reads, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 081/117] fs/nilfs2: Properly bail on errors in grub_nilfs2_btree_node_lookup(), Daniel Kiper, 2021/03/02
- [SECURITY PATCH 093/117] fs/btrfs: Validate the number of stripes/parities in RAID5/6, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 090/117] disk/lvm: Do not overread metadata, Daniel Kiper, 2021/03/02
- [SECURITY PATCH 095/117] kern/parser: Fix a memory leak, Daniel Kiper, 2021/03/02