]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Fix overflow with >2GiB file on HFS+. >4GiB wasn't tested.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 14 Oct 2011 20:41:21 +0000 (22:41 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 14 Oct 2011 20:41:21 +0000 (22:41 +0200)
* grub-core/fs/hfsplus.c (grub_hfsplus_btree): Use more appropriate
types.
(grub_hfsplus_btree_recoffset): Likewise.
(grub_hfsplus_btree_recptr): Likewise.
(grub_hfsplus_find_block): Likewise.
(grub_hfsplus_btree_search): Likewise.
(grub_hfsplus_read_block): Likewise.
(grub_hfsplus_read_file): Likewise.
(grub_hfsplus_mount): Likewise.
(grub_hfsplus_btree_iterate_node): Likewise.
(grub_hfsplus_btree_search): Likewise.
(grub_hfsplus_iterate_dir): Likewise.
(grub_hfsplus_read): A small code simplification.

ChangeLog
grub-core/fs/hfsplus.c

index 3be8005a75e9cc2c4ff8228f38d357b6db3afcb0..9a8b38fd0f69782e7e48539be9ce690a542e9861 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2011-10-14  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Fix overflow with >2GiB file on HFS+. >4GiB wasn't tested.
+
+       * grub-core/fs/hfsplus.c (grub_hfsplus_btree): Use more appropriate
+       types.
+       (grub_hfsplus_btree_recoffset): Likewise.
+       (grub_hfsplus_btree_recptr): Likewise.
+       (grub_hfsplus_find_block): Likewise.
+       (grub_hfsplus_btree_search): Likewise.
+       (grub_hfsplus_read_block): Likewise.
+       (grub_hfsplus_read_file): Likewise.
+       (grub_hfsplus_mount): Likewise.
+       (grub_hfsplus_btree_iterate_node): Likewise.
+       (grub_hfsplus_btree_search): Likewise.
+       (grub_hfsplus_iterate_dir): Likewise.
+       (grub_hfsplus_read): A small code simplification.
+
 2011-10-14  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/kern/emu/hostdisk.c
index 304b321262b550aebd5d272baa02c2cdf83d95a6..245cd93a5d181fd111e60131b0eadc22d34f65be 100644 (file)
@@ -214,7 +214,7 @@ struct grub_fshelp_node
 struct grub_hfsplus_btree
 {
   grub_uint32_t root;
-  int nodesize;
+  grub_size_t nodesize;
 
   /* Catalog file node.  */
   struct grub_fshelp_node file;
@@ -236,7 +236,7 @@ struct grub_hfsplus_data
 
   /* This is the offset into the physical disk for an embedded HFS+
      filesystem (one inside a plain HFS wrapper).  */
-  int embedded_offset;
+  grub_disk_addr_t embedded_offset;
   int case_sensitive;
 };
 
@@ -245,7 +245,7 @@ static grub_dl_t my_mod;
 \f
 /* Return the offset of the record with the index INDEX, in the node
    NODE which is part of the B+ tree BTREE.  */
-static inline unsigned int
+static inline grub_off_t
 grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree,
                           struct grub_hfsplus_btnode *node, int index)
 {
@@ -263,7 +263,7 @@ grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree,
                           struct grub_hfsplus_btnode *node, int index)
 {
   char *cnode = (char *) node;
-  unsigned int offset;
+  grub_off_t offset;
   offset = grub_hfsplus_btree_recoffset (btree, node, index);
   return (struct grub_hfsplus_key *) &cnode[offset];
 }
@@ -272,12 +272,12 @@ grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree,
 /* Find the extent that points to FILEBLOCK.  If it is not in one of
    the 8 extents described by EXTENT, return -1.  In that case set
    FILEBLOCK to the next block.  */
-static int
+static grub_disk_addr_t
 grub_hfsplus_find_block (struct grub_hfsplus_extent *extent,
-                        int *fileblock)
+                        grub_disk_addr_t *fileblock)
 {
   int i;
-  grub_size_t blksleft = *fileblock;
+  grub_disk_addr_t blksleft = *fileblock;
 
   /* First lookup the file in the given extents.  */
   for (i = 0; i < 8; i++)
@@ -288,7 +288,7 @@ grub_hfsplus_find_block (struct grub_hfsplus_extent *extent,
     }
 
   *fileblock = blksleft;
-  return -1;
+  return 0xffffffffffffffffULL;
 }
 
 static grub_err_t
@@ -296,7 +296,8 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
                           struct grub_hfsplus_key_internal *key,
                           int (*compare_keys) (struct grub_hfsplus_key *keya,
                                                struct grub_hfsplus_key_internal *keyb),
-                          struct grub_hfsplus_btnode **matchnode, int *keyoffset);
+                          struct grub_hfsplus_btnode **matchnode, 
+                          grub_off_t *keyoffset);
 
 static int grub_hfsplus_cmp_extkey (struct grub_hfsplus_key *keya,
                                    struct grub_hfsplus_key_internal *keyb);
@@ -307,15 +308,15 @@ static grub_disk_addr_t
 grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
 {
   struct grub_hfsplus_btnode *nnode = 0;
-  int blksleft = fileblock;
+  grub_disk_addr_t blksleft = fileblock;
   struct grub_hfsplus_extent *extents = &node->extents[0];
 
   while (1)
     {
       struct grub_hfsplus_extkey *key;
       struct grub_hfsplus_extkey_internal extoverflow;
-      int blk;
-      int ptr;
+      grub_disk_addr_t blk;
+      grub_off_t ptr;
 
       /* Try to find this block in the current set of extents.  */
       blk = grub_hfsplus_find_block (extents, &blksleft);
@@ -325,7 +326,7 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
       grub_free (nnode);
       nnode = 0;
 
-      if (blk != -1)
+      if (blk != 0xffffffffffffffffULL)
        return (blk
                + (node->data->embedded_offset >> (node->data->log2blksize
                                                   - GRUB_DISK_SECTOR_BITS)));
@@ -376,7 +377,7 @@ static grub_ssize_t
 grub_hfsplus_read_file (grub_fshelp_node_t node,
                        void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
                                           unsigned offset, unsigned length),
-                       int pos, grub_size_t len, char *buf)
+                       grub_off_t pos, grub_size_t len, char *buf)
 {
   return grub_fshelp_read_file (node->data->disk, node, read_hook,
                                pos, len, buf, grub_hfsplus_read_block,
@@ -411,9 +412,9 @@ grub_hfsplus_mount (grub_disk_t disk)
   data->embedded_offset = 0;
   if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC)
     {
-      int extent_start;
-      int ablk_size;
-      int ablk_start;
+      grub_disk_addr_t extent_start;
+      grub_disk_addr_t ablk_size;
+      grub_disk_addr_t ablk_start;
 
       /* See if there's an embedded HFS+ filesystem.  */
       if (grub_be_to_cpu16 (volheader.hfs.embed_sig) != GRUB_HFSPLUS_MAGIC)
@@ -601,10 +602,10 @@ grub_hfsplus_read_symlink (grub_fshelp_node_t node)
 static int
 grub_hfsplus_btree_iterate_node (struct grub_hfsplus_btree *btree,
                                 struct grub_hfsplus_btnode *first_node,
-                                int first_rec,
+                                grub_disk_addr_t first_rec,
                                 int (*hook) (void *record))
 {
-  int rec;
+  grub_disk_addr_t rec;
 
   for (;;)
     {
@@ -642,12 +643,13 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
                           struct grub_hfsplus_key_internal *key,
                           int (*compare_keys) (struct grub_hfsplus_key *keya,
                                                struct grub_hfsplus_key_internal *keyb),
-                          struct grub_hfsplus_btnode **matchnode, int *keyoffset)
+                          struct grub_hfsplus_btnode **matchnode, 
+                          grub_off_t *keyoffset)
 {
   grub_uint64_t currnode;
   char *node;
   struct grub_hfsplus_btnode *nodedesc;
-  int rec;
+  grub_disk_addr_t rec;
 
   node = grub_malloc (btree->nodesize);
   if (! node)
@@ -825,7 +827,7 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir,
 
   struct grub_hfsplus_key_internal intern;
   struct grub_hfsplus_btnode *node;
-  int ptr;
+  grub_disk_addr_t ptr;
 
   /* Create a key that points to the first entry in the directory.  */
   intern.catkey.parent = dir->fileid;
@@ -894,7 +896,6 @@ grub_hfsplus_close (grub_file_t file)
   return GRUB_ERR_NONE;
 }
 
-
 /* Read LEN bytes data from FILE into BUF.  */
 static grub_ssize_t
 grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
@@ -902,13 +903,10 @@ grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
   struct grub_hfsplus_data *data =
     (struct grub_hfsplus_data *) file->data;
 
-  int size = grub_hfsplus_read_file (&data->opened_file, file->read_hook,
+  return grub_hfsplus_read_file (&data->opened_file, file->read_hook,
                                     file->offset, len, buf);
-
-  return size;
 }
 
-
 static grub_err_t
 grub_hfsplus_dir (grub_device_t device, const char *path,
                  int (*hook) (const char *filename,