]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Fix iso9660 filename limitations and fix memory leaks.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 30 Oct 2011 19:23:05 +0000 (20:23 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 30 Oct 2011 19:23:05 +0000 (20:23 +0100)
* grub-core/fs/iso9660.c (set_rockridge): Free sua at the end.
(grub_iso9660_iterate_dir): Fix slash handling in symlinks.

ChangeLog
grub-core/fs/iso9660.c

index cfdbfaedab82b1acda92ebed173d52be1bfcf98a..223afb1e6e698db103fc87bce6b63ef5866481c3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-10-30  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Fix iso9660 filename limitations and fix memory leaks.
+
+       * grub-core/fs/iso9660.c (set_rockridge): Free sua at the end.
+       (grub_iso9660_iterate_dir): Fix slash handling in symlinks.
+
 2011-10-30  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Fix JFS file name length limitations.
index a2e731351863a3f60b97edb77a6193e86a06646b..d4c52bed40cc325979212710597d9f89d248f4e0 100644 (file)
@@ -395,7 +395,10 @@ set_rockridge (struct grub_iso9660_data *data)
                      (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
                       << GRUB_ISO9660_LOG2_BLKSZ), sua_pos,
                      sua_size, sua))
-    return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
+    {
+      grub_free (sua);
+      return grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem");
+    }
 
   entry = (struct grub_iso9660_susp_entry *) sua;
 
@@ -419,8 +422,12 @@ set_rockridge (struct grub_iso9660_data *data)
         extensions.  */
       if (grub_iso9660_susp_iterate (&rootnode,
                                     sua_pos, sua_size, susp_iterate))
-       return grub_errno;
+       {
+         grub_free (sua);
+         return grub_errno;
+       }
     }
+  grub_free (sua);
   return GRUB_ERR_NONE;
 }
 
@@ -516,12 +523,11 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
 {
   struct grub_iso9660_dir dirent;
   grub_off_t offset = 0;
-  char *filename;
+  char *filename = 0;
   int filename_alloc = 0;
   enum grub_fshelp_filetype type;
   grub_off_t len;
   char *symlink = 0;
-  int addslash = 0;
 
   auto void add_part (const char *part, int len);
 
@@ -551,23 +557,30 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
            filename = ".";
          else if (entry->data[0] & GRUB_ISO9660_RR_DOTDOT)
            filename = "..";
-         else
+         else if (entry->len >= 5)
            {
              int size = 1;
-             if (filename)
+             char *old;
+             size = entry->len - 5;
+             old = filename;
+             if (filename_alloc)
                {
                  size += grub_strlen (filename);
-                 grub_realloc (filename,
-                               grub_strlen (filename)
-                               + entry->len);
+                 filename = grub_realloc (filename, size + 1);
                }
              else
                {
-                 size = entry->len - 5;
+                 filename_alloc = 1;
                  filename = grub_zalloc (size + 1);
+                 filename[0] = 0;
+               }
+             if (!filename)
+               {
+                 filename = old;
+                 return grub_errno;
                }
              filename_alloc = 1;
-             grub_strncpy (filename, (char *) &entry->data[1], size);
+             grub_strncat (filename, (char *) &entry->data[1], size);
              filename[size] = '\0';
            }
        }
@@ -601,12 +614,6 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
          /* The symlink is not stored as a POSIX symlink, translate it.  */
          while (pos + sizeof (*entry) < grub_le_to_cpu32 (entry->len))
            {
-             if (addslash)
-               {
-                 add_part ("/", 1);
-                 addslash = 0;
-               }
-
              /* The current position is the `Component Flag'.  */
              switch (entry->data[pos] & 30)
                {
@@ -615,10 +622,10 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
                    /* The data on pos + 2 is the actual data, pos + 1
                       is the length.  Both are part of the `Component
                       Record'.  */
+                   if (symlink && (entry->data[pos] & 1))
+                     add_part ("/", 1);
                    add_part ((char *) &entry->data[pos + 2],
                              entry->data[pos + 1]);
-                   if ((entry->data[pos] & 1))
-                     addslash = 1;
 
                    break;
                  }
@@ -653,7 +660,6 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir,
   for (; offset < len; offset += dirent.len)
     {
       symlink = 0;
-      addslash = 0;
 
       if (read_node (dir, offset, sizeof (dirent), (char *) &dirent))
        return 0;