]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/fs/cpio.c (grub_cpio_find_file): Handle prefix.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 10 May 2012 21:38:01 +0000 (23:38 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 10 May 2012 21:38:01 +0000 (23:38 +0200)
(handle_symlink): Fix off-by-one error.
Canonicalize the target.
(grub_cpio_dir): Canonicalize the name.
Fix memory leak.
Set directory.
(grub_cpio_open): Canonicalize the name.

ChangeLog
grub-core/fs/cpio.c

index 5e9d1a424ee9ba6a520bf6ab67a9696fca850f08..c18c1d1db9b6f23a58967b0a69747e1960fd6d3c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2012-05-10  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * grub-core/fs/cpio.c (grub_cpio_find_file): Handle prefix.
+       (handle_symlink): Fix off-by-one error.
+       Canonicalize the target.
+       (grub_cpio_dir): Canonicalize the name.
+       Fix memory leak.
+       Set directory.
+       (grub_cpio_open): Canonicalize the name.
+
 2012-05-10  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/fs/iso9660.c (grub_iso9660_iterate_dir): Fix symlink
index cadb5c184937d5c6271da7184aaade1a7f51cda3..9234a29591c06de83de8301a19732f87344a8875 100644 (file)
@@ -254,7 +254,7 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name,
       if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd))
        return grub_errno;
 
-      if (!hd.name[0])
+      if (!hd.name[0] && !hd.prefix[0])
        {
          *ofs = 0;
          return GRUB_ERR_NONE;
@@ -313,9 +313,21 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name,
 
       if (!have_longname)
        {
-         *name = grub_strndup (hd.name, sizeof (hd.name));
+         grub_size_t extra_size = 0;
+
+         while (extra_size < sizeof (hd.prefix)
+                && hd.prefix[extra_size])
+           extra_size++;
+         *name = grub_malloc (sizeof (hd.name) + extra_size + 2);
          if (*name == NULL)
            return grub_errno;
+         if (hd.prefix[0])
+           {
+             grub_memcpy (*name, hd.prefix, extra_size);
+             (*name)[extra_size++] = '/';
+           }
+         grub_memcpy (*name + extra_size, hd.name, sizeof (hd.name));
+         (*name)[extra_size + sizeof (hd.name)] = 0;
        }
 
       data->size = read_number (hd.size, sizeof (hd.size));
@@ -457,13 +469,15 @@ handle_symlink (struct grub_cpio_data *data,
 #endif
   if (target[prefixlen] == '/')
     {
-      grub_memmove (target, target + prefixlen, data->size - 1);
-      ptr = target + data->size - 1;
+      grub_memmove (target, target + prefixlen, size);
+      ptr = target + size;
       ptr = grub_stpcpy (ptr, rest);
       *ptr = 0;
       grub_dprintf ("cpio", "symlink redirected %s to %s\n",
                    *name, target);
       grub_free (*name);
+
+      canonicalize (target);
       *name = target;
       *restart = 1;
       return GRUB_ERR_NONE;
@@ -479,6 +493,7 @@ handle_symlink (struct grub_cpio_data *data,
   grub_dprintf ("cpio", "symlink redirected %s to %s\n",
                *name, target);
   grub_free (*name);
+  canonicalize (target);
   *name = target;
   *restart = 1;
   return GRUB_ERR_NONE;
@@ -498,6 +513,7 @@ grub_cpio_dir (grub_device_t device, const char *path_in,
   path = grub_strdup (path_in + 1);
   if (!path)
     return grub_errno;
+  canonicalize (path);
   for (ptr = path + grub_strlen (path) - 1; ptr >= path && *ptr == '/'; ptr--)
     *ptr = 0;
 
@@ -543,12 +559,15 @@ grub_cpio_dir (grub_device_t device, const char *path_in,
            {
              struct grub_dirhook_info info;
              grub_memset (&info, 0, sizeof (info));
-             info.dir = (p != NULL);
+             info.dir = (p != NULL) || ((mode & ATTR_TYPE) == ATTR_DIR);
              info.mtime = mtime;
              info.mtimeset = 1;
 
              if (hook (n, &info))
-               goto fail;
+               {
+                 grub_free (name);
+                 goto fail;
+               }
              grub_free (prev);
              prev = name;
            }
@@ -603,6 +622,8 @@ grub_cpio_open (grub_file_t file, const char *name_in)
   if (!name)
     return grub_errno;
 
+  canonicalize (name);
+
   grub_dl_ref (my_mod);
 
   data = grub_cpio_mount (file->device->disk);