mirror of
https://git.proxmox.com/git/grub2
synced 2025-07-24 15:09:42 +00:00
fs/nilfs2: Don't search children if provided number is too large
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>
This commit is contained in:
parent
20ab8cb44b
commit
37c0eb05cd
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user