grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Fix prefix autodetection when booting from EFI CD-ROM


From: Andrey Borzenkov
Subject: [PATCH] Fix prefix autodetection when booting from EFI CD-ROM
Date: Thu, 31 Jan 2013 16:24:00 +0400

Fix autodetection of $prefix when booted from EFI CD-ROM.

Based on patch from Matthew Garrett, modified to not overwrite
memory returned by device path protocol handler and rebased to
current trunk.

Additionally fixes potential memory leak - dup_dp was not deallocated
if device path was not found.

Signed-off-by: Andrey Borzenkov <address@hidden>

---
 grub-core/disk/efi/efidisk.c |  121 +++++++++++++++++++++++-------------------
 1 file changed, 66 insertions(+), 55 deletions(-)

diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c
index 98cd226..15c8109 100644
--- a/grub-core/disk/efi/efidisk.c
+++ b/grub-core/disk/efi/efidisk.c
@@ -775,67 +775,78 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
   if (! ldp)
     return 0;
 
-  if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
-      && (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp)
-         == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
+  if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
     {
-      struct grub_efidisk_get_device_name_ctx ctx;
-      char *dev_name;
-      grub_efi_device_path_t *dup_dp, *dup_ldp;
-      grub_disk_t parent = 0;
-
-      /* It is necessary to duplicate the device path so that GRUB
-        can overwrite it.  */
-      dup_dp = duplicate_device_path (dp);
-      if (! dup_dp)
-       return 0;
-
-      dup_ldp = find_last_device_path (dup_dp);
-      dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
-      dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
-      dup_ldp->length[0] = sizeof (*dup_ldp);
-      dup_ldp->length[1] = 0;
+      int is_cdrom = 0;
 
-      if (!get_diskname_from_path (dup_dp, device_name))
-       return 0;
-      parent = grub_disk_open (device_name);
-      grub_free (dup_dp);
-
-      if (! parent)
-       return 0;
-
-      /* Find a partition which matches the hard drive device path.  */
-      ctx.partition_name = NULL;
-      grub_memcpy (&ctx.hd, ldp, sizeof (ctx.hd));
-      if (ctx.hd.partition_start == 0
-         && ctx.hd.partition_size == grub_disk_get_size (parent))
-       {
-         dev_name = grub_strdup (parent->name);
-       }
-      else
+      switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp))
        {
-         grub_partition_iterate (parent, grub_efidisk_get_device_name_iter,
-                                 &ctx);
-
-         if (! ctx.partition_name)
+         case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
+           is_cdrom = 1;
+           /* Intentionally fall through */
+         case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
            {
+             struct grub_efidisk_get_device_name_ctx ctx;
+             char *dev_name;
+             grub_efi_device_path_t *dup_dp, *dup_ldp;
+             grub_disk_t parent = 0;
+
+             /* It is necessary to duplicate the device path so that GRUB
+                can overwrite it.  */
+             dup_dp = duplicate_device_path (dp);
+             if (! dup_dp)
+               return 0;
+
+             dup_ldp = find_last_device_path (dup_dp);
+             dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
+             dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+             dup_ldp->length[0] = sizeof (*dup_ldp);
+             dup_ldp->length[1] = 0;
+
+             if (!get_diskname_from_path (dup_dp, device_name))
+               {
+                 grub_free (dup_dp);
+                 return 0;
+               }
+             grub_free (dup_dp);
+             if (is_cdrom)
+               return grub_strdup (device_name);
+
+             parent = grub_disk_open (device_name);
+             if (! parent)
+               return 0;
+
+             /* Find a partition which matches the hard drive device path.  */
+             ctx.partition_name = NULL;
+             grub_memcpy (&ctx.hd, ldp, sizeof (ctx.hd));
+             if (ctx.hd.partition_start == 0
+                 && ctx.hd.partition_size == grub_disk_get_size (parent))
+               {
+                 dev_name = grub_strdup (parent->name);
+               }
+             else
+               {
+                 grub_partition_iterate (parent, 
grub_efidisk_get_device_name_iter,
+                                         &ctx);
+
+                 if (! ctx.partition_name)
+                   {
+                     grub_disk_close (parent);
+                     return 0;
+                   }
+
+                 dev_name = grub_xasprintf ("%s,%s", parent->name,
+                                            ctx.partition_name);
+                 grub_free (ctx.partition_name);
+               }
              grub_disk_close (parent);
-             return 0;
-           }
 
-         dev_name = grub_xasprintf ("%s,%s", parent->name,
-                                    ctx.partition_name);
-         grub_free (ctx.partition_name);
+             return dev_name;
+           }
        }
-      grub_disk_close (parent);
-
-      return dev_name;
-    }
-  else
-    {
-      /* This should be an entire disk.  */
-      if (!get_diskname_from_path (dp, device_name))
-       return 0;
-      return grub_strdup (device_name);
     }
+  /* This may be guessed device - floppy, cdrom or entire disk.  */
+  if (!get_diskname_from_path (dp, device_name))
+    return 0;
+  return grub_strdup (device_name);
 }
-- 
tg: (4b9ea2e..) u/efi-cdrom-prefix (depends on: master)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]