]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
efi: Fix gcc9 error -Waddress-of-packed-member
authorMichael Chang <mchang@suse.com>
Thu, 11 Apr 2019 09:14:09 +0000 (17:14 +0800)
committerDaniel Kiper <daniel.kiper@oracle.com>
Tue, 23 Apr 2019 09:37:08 +0000 (11:37 +0200)
The address of fp->path_name could be unaligned since seeking into the
device path buffer for a given node could end in byte boundary.

The fix is allocating aligned buffer by grub_malloc for holding the
UTF16 string copied from fp->path_name, and after using that buffer as
argument for grub_utf16_to_utf8 to convert it to UTF8 string.

[  255s] ../../grub-core/kern/efi/efi.c: In function 'grub_efi_get_filename':
[  255s] ../../grub-core/kern/efi/efi.c:410:60: error: taking address of packed member of 'struct grub_efi_file_path_device_path' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[  255s]   410 |    p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, fp->path_name, len);
[  255s]       |                                                          ~~^~~~~~~~~~~
[  255s] ../../grub-core/kern/efi/efi.c: In function 'grub_efi_print_device_path':
[  255s] ../../grub-core/kern/efi/efi.c:900:33: error: taking address of packed member of 'struct grub_efi_file_path_device_path' may result in an unaligned pointer value [-Werror=address-of-packed-member]
[  255s]   900 |     *grub_utf16_to_utf8 (buf, fp->path_name,
[  255s]       |                               ~~^~~~~~~~~~~

Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/kern/efi/efi.c

index 84e68cf31ce14c22c321bfacf58a5fe1a54b4477..6e1ceb90516fb87da0eae5e9ba3d65671474c702 100644 (file)
@@ -372,6 +372,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
        {
          grub_efi_file_path_device_path_t *fp;
          grub_efi_uint16_t len;
+         grub_efi_char16_t *dup_name;
 
          *p++ = '/';
 
@@ -382,7 +383,16 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
          while (len > 0 && fp->path_name[len - 1] == 0)
            len--;
 
-         p = (char *) grub_utf16_to_utf8 ((unsigned char *) p, fp->path_name, len);
+         dup_name = grub_malloc (len * sizeof (*dup_name));
+         if (!dup_name)
+           {
+             grub_free (name);
+             return NULL;
+           }
+         p = (char *) grub_utf16_to_utf8 ((unsigned char *) p,
+                                           grub_memcpy (dup_name, fp->path_name, len * sizeof (*dup_name)),
+                                           len);
+         grub_free (dup_name);
        }
 
       dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
@@ -812,9 +822,20 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
                fp = (grub_efi_file_path_device_path_t *) dp;
                buf = grub_malloc ((len - 4) * 2 + 1);
                if (buf)
-                 *grub_utf16_to_utf8 (buf, fp->path_name,
+                 {
+                   grub_efi_char16_t *dup_name = grub_malloc (len - 4);
+                   if (!dup_name)
+                     {
+                       grub_errno = GRUB_ERR_NONE;
+                       grub_printf ("/File((null))");
+                       grub_free (buf);
+                       break;
+                     }
+                   *grub_utf16_to_utf8 (buf, grub_memcpy (dup_name, fp->path_name, len - 4),
                                       (len - 4) / sizeof (grub_efi_char16_t))
-                   = '\0';
+                     = '\0';
+                   grub_free (dup_name);
+                 }
                else
                  grub_errno = GRUB_ERR_NONE;
                grub_printf ("/File(%s)", buf);