File grub2-ppc64-cas-fix-double-free.patch of Package grub2

Index: grub-2.04~rc1/grub-core/kern/ieee1275/openfw.c
===================================================================
--- grub-2.04~rc1.orig/grub-core/kern/ieee1275/openfw.c
+++ grub-2.04~rc1/grub-core/kern/ieee1275/openfw.c
@@ -595,7 +595,7 @@ grub_ieee1275_canonicalise_devname (cons
 
 /* Check if it's a CAS reboot. If so, set the script to be executed.  */
 int
-grub_ieee1275_cas_reboot (char *script)
+grub_ieee1275_cas_reboot (char **script)
 {
   grub_uint32_t ibm_ca_support_reboot;
   grub_uint32_t ibm_fw_nbr_reboots;
@@ -628,16 +628,37 @@ grub_ieee1275_cas_reboot (char *script)
 
   if (ibm_ca_support_reboot || ibm_fw_nbr_reboots)
     {
-      if (! grub_ieee1275_get_property_length (options, "boot-last-label", &actual))
-        {
-          if (actual > 1024)
-            script = grub_realloc (script, actual + 1);
-          grub_ieee1275_get_property (options, "boot-last-label", script, actual,
-                                      &actual);
-          return 0;
-        }
+      grub_ssize_t len;
+      char *buf;
+
+      if (grub_ieee1275_get_property_length (options, "boot-last-label", &len)
+		|| len <= 0)
+	{
+	  grub_dprintf ("ieee1275", "boot-last-label missing or invalid\n");
+	  goto out;
+	}
+      /* The returned property string length may not include terminating null byte, and in
+         a bid to avoid out of bound access we allocate one more byte to add it back */
+      buf = grub_malloc ((grub_size_t)len + 1);
+      if (!buf)
+	{
+	  grub_print_error ();
+	  goto out;
+	}
+      if (grub_ieee1275_get_property (options, "boot-last-label", buf, (grub_size_t)len + 1, &actual)
+		|| actual < 0)
+	{
+	  grub_dprintf ("ieee1275", "error while get boot-last-label property\n");
+	  grub_free (buf);
+	  goto out;
+	}
+      /* Add terminating null byte */
+      buf[len] = '\0';
+      *script = buf;
+      return 0;
     }
 
+out:
   grub_ieee1275_set_boot_last_label ("");
 
   return -1;
@@ -651,8 +672,9 @@ int grub_ieee1275_set_boot_last_label (c
   grub_dprintf("ieee1275", "set boot_last_label (size: %" PRIxGRUB_SIZE ")\n", grub_strlen(text));
   if (! grub_ieee1275_finddevice ("/options", &options) &&
       options != (grub_ieee1275_ihandle_t) -1)
+    /* To be on the safe side, set the property string with terminating null byte */
     grub_ieee1275_set_property (options, "boot-last-label", text,
-                                grub_strlen (text), &actual);
+                                grub_strlen (text) + 1, &actual);
   return 0;
 }
 
Index: grub-2.04~rc1/grub-core/normal/main.c
===================================================================
--- grub-2.04~rc1.orig/grub-core/normal/main.c
+++ grub-2.04~rc1/grub-core/normal/main.c
@@ -281,10 +281,9 @@ grub_normal_execute (const char *config,
 #ifdef GRUB_MACHINE_IEEE1275
       int boot;
       boot = 0;
-      char *script;
+      char *script = NULL;
       char *dummy[1] = { NULL };
-      script = grub_malloc (1024);
-      if (! grub_ieee1275_cas_reboot (script))
+      if (! grub_ieee1275_cas_reboot (&script) && script)
         {
           if (! grub_script_execute_new_scope (script, 0, dummy))
             boot = 1;
Index: grub-2.04~rc1/include/grub/ieee1275/ieee1275.h
===================================================================
--- grub-2.04~rc1.orig/include/grub/ieee1275/ieee1275.h
+++ grub-2.04~rc1/include/grub/ieee1275/ieee1275.h
@@ -263,7 +263,7 @@ int EXPORT_FUNC(grub_ieee1275_devalias_n
 void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *alias);
 void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath,
 						struct grub_ieee1275_devalias *alias);
-int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script);
+int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char **script);
 int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text);
 
 char *EXPORT_FUNC(grub_ieee1275_get_boot_dev) (void);