]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
chainloader: Fix gcc9 error -Waddress-of-packed-member
authorMichael Chang <mchang@suse.com>
Thu, 11 Apr 2019 09:14:08 +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 using aligned buffer allocated by grub_malloc for receiving
the converted UTF16 string by grub_utf8_to_utf16 and also the processing
after. The resulting string then gets copied to fp->path_name.

[  243s] ../../grub-core/loader/efi/chainloader.c: In function 'copy_file_path':
[  243s] ../../grub-core/loader/efi/chainloader.c:136:32: 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]
[  243s]   136 |   size = grub_utf8_to_utf16 (fp->path_name, len * GRUB_MAX_UTF16_PER_UTF8,
[  243s]       |                              ~~^~~~~~~~~~~
[  243s] ../../grub-core/loader/efi/chainloader.c:138:12: 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]
[  243s]   138 |   for (p = fp->path_name; p < fp->path_name + size; p++)
[  243s]       |            ^~

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

index f706b1ac30a333aca71e05286654c34c86fb75a0..cd92ea3f24b058f9f93fb5af74178e9ddaeb3dc9 100644 (file)
@@ -110,21 +110,27 @@ static void
 copy_file_path (grub_efi_file_path_device_path_t *fp,
                const char *str, grub_efi_uint16_t len)
 {
-  grub_efi_char16_t *p;
+  grub_efi_char16_t *p, *path_name;
   grub_efi_uint16_t size;
 
   fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
   fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
 
-  size = grub_utf8_to_utf16 (fp->path_name, len * GRUB_MAX_UTF16_PER_UTF8,
+  path_name = grub_malloc (len * GRUB_MAX_UTF16_PER_UTF8 * sizeof (*path_name));
+  if (!path_name)
+    return;
+
+  size = grub_utf8_to_utf16 (path_name, len * GRUB_MAX_UTF16_PER_UTF8,
                             (const grub_uint8_t *) str, len, 0);
-  for (p = fp->path_name; p < fp->path_name + size; p++)
+  for (p = path_name; p < path_name + size; p++)
     if (*p == '/')
       *p = '\\';
 
+  grub_memcpy (fp->path_name, path_name, size * sizeof (*fp->path_name));
   /* File Path is NULL terminated */
   fp->path_name[size++] = '\0';
   fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
+  grub_free (path_name);
 }
 
 static grub_efi_device_path_t *