]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
hfsplus: Fix potential access to uninited memory on invalid FS
authorVladimir Serbinenko <phcoder@gmail.com>
Fri, 6 Mar 2015 21:33:20 +0000 (22:33 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Fri, 6 Mar 2015 21:33:20 +0000 (22:33 +0100)
grub-core/fs/hfsplus.c
include/grub/hfsplus.h

index 8f07f8544779fa276e8f6ccc060de5d2f638000e..110d8581513c0d9823a4267ec2279f7334f80cdc 100644 (file)
@@ -336,6 +336,9 @@ grub_hfsplus_mount (grub_disk_t disk)
   data->case_sensitive = ((magic == GRUB_HFSPLUSX_MAGIC) &&
                          (header.key_compare == GRUB_HFSPLUSX_BINARYCOMPARE));
 
+  if (data->catalog_tree.nodesize < 2)
+    goto fail;
+
   if (grub_hfsplus_read_file (&data->extoverflow_tree.file, 0, 0,
                              sizeof (struct grub_hfsplus_btnode),
                              sizeof (header), (char *) &header) <= 0)
@@ -350,6 +353,9 @@ grub_hfsplus_mount (grub_disk_t disk)
   data->extoverflow_tree.root = grub_be_to_cpu32 (header.root);
   data->extoverflow_tree.nodesize = grub_be_to_cpu16 (header.nodesize);
 
+  if (data->extoverflow_tree.nodesize < 2)
+    goto fail;
+
   if (grub_hfsplus_read_file (&data->attr_tree.file, 0, 0,
                              sizeof (struct grub_hfsplus_btnode),
                              sizeof (header), (char *) &header) <= 0)
index 8ba8f32468b697fbc613676efa492dc091596bc5..117740ae26968a85094e9dd2c007449b443a33ef 100644 (file)
@@ -171,7 +171,7 @@ struct grub_hfsplus_catkey
   grub_uint16_t keylen;
   grub_uint32_t parent;
   grub_uint16_t namelen;
-  grub_uint16_t name[30];
+  grub_uint16_t name[0];
 } GRUB_PACKED;
 
 /* The on disk layout of an extent overflow file key.  */
@@ -207,12 +207,14 @@ struct grub_hfsplus_btnode
 
 /* Return the offset of the record with the index INDEX, in the node
    NODE which is part of the B+ tree BTREE.  */
-static inline grub_off_t
+static inline grub_uint16_t
 grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree,
-                          struct grub_hfsplus_btnode *node, int index)
+                          struct grub_hfsplus_btnode *node, unsigned index)
 {
   char *cnode = (char *) node;
   void *recptr;
+  if (btree->nodesize < index * sizeof (grub_uint16_t) + 2)
+    index = 0;
   recptr = (&cnode[btree->nodesize - index * sizeof (grub_uint16_t) - 2]);
   return grub_be_to_cpu16 (grub_get_unaligned16 (recptr));
 }
@@ -221,11 +223,13 @@ grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree,
    NODE which is part of the B+ tree BTREE.  */
 static inline struct grub_hfsplus_key *
 grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree,
-                          struct grub_hfsplus_btnode *node, int index)
+                          struct grub_hfsplus_btnode *node, unsigned index)
 {
   char *cnode = (char *) node;
-  grub_off_t offset;
+  grub_uint16_t offset;
   offset = grub_hfsplus_btree_recoffset (btree, node, index);
+  if (offset > btree->nodesize - sizeof (struct grub_hfsplus_key))
+    offset = 0;
   return (struct grub_hfsplus_key *) &cnode[offset];
 }