* gnu/packages/patches/grub-check-error-efibootmgr.patch: Add hunk to correct uninitialized variable.
		
			
				
	
	
		
			197 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| Without this patch, GRUB may proceed to wipe all firmware boot entries
 | ||
| and report a successful installation, even if efibootmgr hit an error.
 | ||
| 
 | ||
| Origin URL:
 | ||
| https://git.sv.gnu.org/cgit/grub.git/commit/?id=6400613ad0b463abc93362086a491cd2a5e99b0d
 | ||
| 
 | ||
| From 6400613ad0b463abc93362086a491cd2a5e99b0d Mon Sep 17 00:00:00 2001
 | ||
| From: Steve McIntyre <steve@einval.com>
 | ||
| Date: Wed, 31 Jan 2018 21:49:36 +0000
 | ||
| Subject: Make grub-install check for errors from efibootmgr
 | ||
| 
 | ||
| Code is currently ignoring errors from efibootmgr, giving users
 | ||
| clearly bogus output like:
 | ||
| 
 | ||
|         Setting up grub-efi-amd64 (2.02~beta3-4) ...
 | ||
|         Installing for x86_64-efi platform.
 | ||
|         Could not delete variable: No space left on device
 | ||
|         Could not prepare Boot variable: No space left on device
 | ||
|         Installation finished. No error reported.
 | ||
| 
 | ||
| and then potentially unbootable systems. If efibootmgr fails, grub-install
 | ||
| should know that and report it!
 | ||
| 
 | ||
| We've been using similar patch in Debian now for some time, with no ill effects.
 | ||
| 
 | ||
| diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
 | ||
| index a3fcfca..ca448bc 100644
 | ||
| --- a/grub-core/osdep/unix/platform.c
 | ||
| +++ b/grub-core/osdep/unix/platform.c
 | ||
| @@ -78,19 +78,20 @@ get_ofpathname (const char *dev)
 | ||
|  		   dev);
 | ||
|  }
 | ||
|  
 | ||
| -static void
 | ||
| +static int
 | ||
|  grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
 | ||
|  {
 | ||
|    int fd;
 | ||
|    pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd);
 | ||
|    char *line = NULL;
 | ||
|    size_t len = 0;
 | ||
| +  int rc;
 | ||
|  
 | ||
|    if (!pid)
 | ||
|      {
 | ||
|        grub_util_warn (_("Unable to open stream from %s: %s"),
 | ||
|  		      "efibootmgr", strerror (errno));
 | ||
| -      return;
 | ||
| +      return errno;
 | ||
|      }
 | ||
|  
 | ||
|    FILE *fp = fdopen (fd, "r");
 | ||
| @@ -98,7 +99,7 @@ grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
 | ||
|      {
 | ||
|        grub_util_warn (_("Unable to open stream from %s: %s"),
 | ||
|  		      "efibootmgr", strerror (errno));
 | ||
| -      return;
 | ||
| +      return errno;
 | ||
|      }
 | ||
|  
 | ||
|    line = xmalloc (80);
 | ||
| @@ -119,23 +120,25 @@ grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
 | ||
|        bootnum = line + sizeof ("Boot") - 1;
 | ||
|        bootnum[4] = '\0';
 | ||
|        if (!verbosity)
 | ||
| -	grub_util_exec ((const char * []){ "efibootmgr", "-q",
 | ||
| +	rc = grub_util_exec ((const char * []){ "efibootmgr", "-q",
 | ||
|  	      "-b", bootnum,  "-B", NULL });
 | ||
|        else
 | ||
| -	grub_util_exec ((const char * []){ "efibootmgr",
 | ||
| +	rc = grub_util_exec ((const char * []){ "efibootmgr",
 | ||
|  	      "-b", bootnum, "-B", NULL });
 | ||
|      }
 | ||
|  
 | ||
|    free (line);
 | ||
| +  return rc;
 | ||
|  }
 | ||
|  
 | ||
| -void
 | ||
| +int
 | ||
|  grub_install_register_efi (grub_device_t efidir_grub_dev,
 | ||
|  			   const char *efifile_path,
 | ||
|  			   const char *efi_distributor)
 | ||
|  {
 | ||
|    const char * efidir_disk;
 | ||
|    int efidir_part;
 | ||
| +  int ret;
 | ||
|    efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk);
 | ||
|    efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1;
 | ||
|  
 | ||
| @@ -151,23 +154,26 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
 | ||
|    grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL });
 | ||
|  #endif
 | ||
|    /* Delete old entries from the same distributor.  */
 | ||
| -  grub_install_remove_efi_entries_by_distributor (efi_distributor);
 | ||
| +  ret = grub_install_remove_efi_entries_by_distributor (efi_distributor);
 | ||
| +  if (ret)
 | ||
| +    return ret;
 | ||
|  
 | ||
|    char *efidir_part_str = xasprintf ("%d", efidir_part);
 | ||
|  
 | ||
|    if (!verbosity)
 | ||
| -    grub_util_exec ((const char * []){ "efibootmgr", "-q",
 | ||
| +    ret = grub_util_exec ((const char * []){ "efibootmgr", "-q",
 | ||
|  	  "-c", "-d", efidir_disk,
 | ||
|  	  "-p", efidir_part_str, "-w",
 | ||
|  	  "-L", efi_distributor, "-l", 
 | ||
|  	  efifile_path, NULL });
 | ||
|    else
 | ||
| -    grub_util_exec ((const char * []){ "efibootmgr",
 | ||
| +    ret = grub_util_exec ((const char * []){ "efibootmgr",
 | ||
|  	  "-c", "-d", efidir_disk,
 | ||
|  	  "-p", efidir_part_str, "-w",
 | ||
|  	  "-L", efi_distributor, "-l", 
 | ||
|  	  efifile_path, NULL });
 | ||
|    free (efidir_part_str);
 | ||
| +  return ret;
 | ||
|  }
 | ||
|  
 | ||
|  void
 | ||
| diff --git a/include/grub/util/install.h b/include/grub/util/install.h
 | ||
| index 5910b0c..0dba8b6 100644
 | ||
| --- a/include/grub/util/install.h
 | ||
| +++ b/include/grub/util/install.h
 | ||
| @@ -210,7 +210,7 @@ grub_install_create_envblk_file (const char *name);
 | ||
|  const char *
 | ||
|  grub_install_get_default_x86_platform (void);
 | ||
|  
 | ||
| -void
 | ||
| +int
 | ||
|  grub_install_register_efi (grub_device_t efidir_grub_dev,
 | ||
|  			   const char *efifile_path,
 | ||
|  			   const char *efi_distributor);
 | ||
| diff --git a/util/grub-install.c b/util/grub-install.c
 | ||
| index 5e4cdfd..690f180 100644
 | ||
| --- a/util/grub-install.c
 | ||
| +++ b/util/grub-install.c
 | ||
| @@ -1848,9 +1848,13 @@ main (int argc, char *argv[])
 | ||
|  	  if (!removable && update_nvram)
 | ||
|  	    {
 | ||
|  	      /* Try to make this image bootable using the EFI Boot Manager, if available.  */
 | ||
| -	      grub_install_register_efi (efidir_grub_dev,
 | ||
| -					 "\\System\\Library\\CoreServices",
 | ||
| -					 efi_distributor);
 | ||
| +	      int ret;
 | ||
| +	      ret = grub_install_register_efi (efidir_grub_dev,
 | ||
| +					       "\\System\\Library\\CoreServices",
 | ||
| +					       efi_distributor);
 | ||
| +	      if (ret)
 | ||
| +	        grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
 | ||
| +				 strerror (ret));
 | ||
|  	    }
 | ||
|  
 | ||
|  	  grub_device_close (ins_dev);
 | ||
| @@ -1871,6 +1875,7 @@ main (int argc, char *argv[])
 | ||
|  	{
 | ||
|  	  char * efifile_path;
 | ||
|  	  char * part;
 | ||
| +	  int ret;
 | ||
|  
 | ||
|  	  /* Try to make this image bootable using the EFI Boot Manager, if available.  */
 | ||
|  	  if (!efi_distributor || efi_distributor[0] == '\0')
 | ||
| @@ -1887,7 +1892,10 @@ main (int argc, char *argv[])
 | ||
|  			  efidir_grub_dev->disk->name,
 | ||
|  			  (part ? ",": ""), (part ? : ""));
 | ||
|  	  grub_free (part);
 | ||
| -	  grub_install_register_efi (efidir_grub_dev,
 | ||
| -				     efifile_path, efi_distributor);
 | ||
| +	  ret = grub_install_register_efi (efidir_grub_dev,
 | ||
| +					   efifile_path, efi_distributor);
 | ||
| +	  if (ret)
 | ||
| +	    grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
 | ||
| +			     strerror (ret));
 | ||
|  	}
 | ||
|        break;
 | ||
| 
 | ||
| 
 | ||
| Below is a followup to the patch above: the uninitialized variable could lead
 | ||
| ‘grub-install’ to error out when it shouldn’t (seen on an AArch64 box where
 | ||
| ‘grub_install_remove_efi_entries_by_distributor’ didn't have any entry to
 | ||
| remove):
 | ||
| 
 | ||
|   grub-install: error: efibootmgr failed to register the boot entry: Unknown error 65535.
 | ||
| 
 | ||
| See <http://lists.gnu.org/archive/html/bug-grub/2018-10/msg00006.html>.
 | ||
| 
 | ||
| --- grub-2.02/grub-core/osdep/unix/platform.c	2018-10-17 22:21:53.015284846 +0200
 | ||
| +++ grub-2.02/grub-core/osdep/unix/platform.c	2018-10-17 22:21:55.595271222 +0200
 | ||
| @@ -85,7 +85,7 @@ grub_install_remove_efi_entries_by_distr
 | ||
|    pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd);
 | ||
|    char *line = NULL;
 | ||
|    size_t len = 0;
 | ||
| -  int rc;
 | ||
| +  int rc = 0;
 | ||
|  
 | ||
|    if (!pid)
 | ||
|      {
 |