]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
types: Split aligned and packed guids
authorVladimir Serbinenko <phcoder@gmail.com>
Sun, 13 Aug 2023 07:18:23 +0000 (09:18 +0200)
committerVladimir Serbinenko <phcoder@gmail.com>
Wed, 8 Nov 2023 04:04:24 +0000 (05:04 +0100)
On ia64 alignment requirements are strict. When we pass a pointer to
UUID it needs to be at least 4-byte aligned or EFI will crash.
On the other hand in device path there is no padding for UUID, so we
need 2 types in one formor another. Make 4-byte aligned and unaligned types

The code is structured in a way to accept unaligned inputs
in most cases and supply 4-byte aligned outputs.

Efiemu case is a bit ugly because there inputs and outputs are
reversed and so we need careful casts to account for this
inversion.

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/commands/efi/lsefi.c
grub-core/efiemu/runtime/efiemu.c
grub-core/kern/efi/efi.c
grub-core/kern/misc.c
grub-core/loader/i386/xnu.c
include/grub/efi/api.h
include/grub/efiemu/efiemu.h
include/grub/efiemu/runtime.h
include/grub/types.h

index 95cba5bafa036674e9d696fd56ffa741d1b80ccf..7b8316d4184c8b35a382606b1dc2034c131d1b53 100644 (file)
@@ -96,7 +96,7 @@ grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)),
       grub_efi_handle_t handle = handles[i];
       grub_efi_status_t status;
       grub_efi_uintn_t num_protocols;
-      grub_guid_t **protocols;
+      grub_packed_guid_t **protocols;
       grub_efi_device_path_t *dp;
 
       grub_printf ("Handle %p\n", handle);
index c84b3065239ed8ad795af28e80f1d72e189760ce..51dc021145e060c5c3f60af1b6c0abac78916262 100644 (file)
@@ -66,7 +66,7 @@ efiemu_convert_pointer (grub_efi_uintn_t debug_disposition,
 
 grub_efi_status_t __grub_efi_api
 efiemu_get_variable (grub_efi_char16_t *variable_name,
-                    const grub_guid_t *vendor_guid,
+                    const grub_packed_guid_t *vendor_guid,
                     grub_efi_uint32_t *attributes,
                     grub_efi_uintn_t *data_size,
                     void *data);
@@ -74,11 +74,11 @@ efiemu_get_variable (grub_efi_char16_t *variable_name,
 grub_efi_status_t __grub_efi_api
 efiemu_get_next_variable_name (grub_efi_uintn_t *variable_name_size,
                               grub_efi_char16_t *variable_name,
-                              grub_guid_t *vendor_guid);
+                              grub_packed_guid_t *vendor_guid);
 
 grub_efi_status_t __grub_efi_api
 efiemu_set_variable (grub_efi_char16_t *variable_name,
-                    const grub_guid_t *vendor_guid,
+                    const grub_packed_guid_t *vendor_guid,
                     grub_efi_uint32_t attributes,
                     grub_efi_uintn_t data_size,
                     void *data);
@@ -416,7 +416,7 @@ EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
 
 /* Find variable by name and GUID. */
 static struct efi_variable *
-find_variable (const grub_guid_t *vendor_guid,
+find_variable (const grub_packed_guid_t *vendor_guid,
               grub_efi_char16_t *variable_name)
 {
   grub_uint8_t *ptr;
@@ -438,7 +438,7 @@ find_variable (const grub_guid_t *vendor_guid,
 
 grub_efi_status_t __grub_efi_api
 EFI_FUNC (efiemu_get_variable) (grub_efi_char16_t *variable_name,
-                               const grub_guid_t *vendor_guid,
+                               const grub_packed_guid_t *vendor_guid,
                                grub_efi_uint32_t *attributes,
                                grub_efi_uintn_t *data_size,
                                void *data)
@@ -464,7 +464,7 @@ EFI_FUNC (efiemu_get_variable) (grub_efi_char16_t *variable_name,
 grub_efi_status_t __grub_efi_api EFI_FUNC
 (efiemu_get_next_variable_name) (grub_efi_uintn_t *variable_name_size,
                                 grub_efi_char16_t *variable_name,
-                                grub_guid_t *vendor_guid)
+                                grub_packed_guid_t *vendor_guid)
 {
   struct efi_variable *efivar;
   LOG ('l');
@@ -503,7 +503,7 @@ grub_efi_status_t __grub_efi_api EFI_FUNC
 
 grub_efi_status_t __grub_efi_api
 EFI_FUNC (efiemu_set_variable) (grub_efi_char16_t *variable_name,
-                               const grub_guid_t *vendor_guid,
+                               const grub_packed_guid_t *vendor_guid,
                                grub_efi_uint32_t attributes,
                                grub_efi_uintn_t data_size,
                                void *data)
@@ -597,9 +597,30 @@ struct grub_efi_runtime_services efiemu_runtime_services =
   .set_virtual_address_map = efiemu_set_virtual_address_map,
   .convert_pointer = efiemu_convert_pointer,
 
-  .get_variable = efiemu_get_variable,
-  .get_next_variable_name = efiemu_get_next_variable_name,
-  .set_variable = efiemu_set_variable,
+  /*
+    The code is structured in a way to accept unaligned inputs
+    in most cases and supply 4-byte aligned outputs.
+
+    Efiemu case is a bit ugly because there inputs and outputs are
+    reversed and so we need careful casts to account for this
+    inversion.
+   */
+  .get_variable = (grub_efi_status_t
+                  (__grub_efi_api *) (grub_efi_char16_t *variable_name,
+                                      const grub_guid_t *vendor_guid,
+                                      grub_efi_uint32_t *attributes,
+                                      grub_efi_uintn_t *data_size,
+                                      void *data)) efiemu_get_variable,
+  .get_next_variable_name = (grub_efi_status_t
+                            (__grub_efi_api *) (grub_efi_uintn_t *variable_name_size,
+                                                grub_efi_char16_t *variable_name,
+                                                grub_guid_t *vendor_guid)) efiemu_get_next_variable_name,
+  .set_variable = (grub_efi_status_t
+                  (__grub_efi_api *) (grub_efi_char16_t *variable_name,
+                                      const grub_guid_t *vendor_guid,
+                                      grub_efi_uint32_t attributes,
+                                      grub_efi_uintn_t data_size,
+                                      void *data)) efiemu_set_variable,
   .get_next_high_monotonic_count = efiemu_get_next_high_monotonic_count,
 
   .reset_system = efiemu_reset_system
index e53808307249a1e37982a59046d4acea80a4c404..b93ae3aba12db0337e5713634456f448e602f4bd 100644 (file)
@@ -1039,7 +1039,7 @@ grub_efi_find_configuration_table (const grub_guid_t *target_guid)
 
   for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
     {
-      grub_guid_t *guid =
+      grub_packed_guid_t *guid =
        &grub_efi_system_table->configuration_table[i].vendor_guid;
 
       if (! grub_memcmp (guid, target_guid, sizeof (grub_guid_t)))
index b57249acb81b5acb7a444c6ec9e2c88cab42ba5f..7cee5d75c3c2c85ece5662c60de9257eaa53bab4 100644 (file)
@@ -1068,7 +1068,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0,
          if (*(fmt) == 'G')
            {
              ++fmt;
-             grub_guid_t *guid = (grub_guid_t *)(grub_addr_t) curarg;
+             grub_packed_guid_t *guid = (grub_packed_guid_t *)(grub_addr_t) curarg;
              write_number (str, &count, max_len, 8, 0, '0', 'x', guid->data1);
              write_char (str, &count, max_len, '-');
              write_number (str, &count, max_len, 4, 0, '0', 'x', guid->data2);
index 4e31ce99ae96d5ecd2ff2ffcda0d659d1c83c0e9..b91e2f840196de765d1455ce4178b66d088d25cb 100644 (file)
@@ -694,7 +694,7 @@ grub_cpu_xnu_fill_devicetree (grub_uint64_t *fsbfreq_out)
     {
       void *ptr;
       struct grub_xnu_devtree_key *curkey;
-      grub_guid_t guid;
+      grub_packed_guid_t guid;
       char guidbuf[64];
 
       /* Retrieve current key. */
index d3eaef3fb93018d33b86f330fcf2ba8c20cf37b1..d44d00ad7d5b9e33fdae4282e4e367544ece3666 100644 (file)
@@ -730,7 +730,7 @@ typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_
 struct grub_efi_vendor_device_path
 {
   grub_efi_device_path_t header;
-  grub_guid_t vendor_guid;
+  grub_packed_guid_t vendor_guid;
   grub_efi_uint8_t vendor_defined_data[0];
 } GRUB_PACKED;
 typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t;
@@ -974,7 +974,7 @@ typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t;
 struct grub_efi_vendor_media_device_path
 {
   grub_efi_device_path_t header;
-  grub_guid_t vendor_guid;
+  grub_packed_guid_t vendor_guid;
   grub_efi_uint8_t vendor_defined_data[0];
 } GRUB_PACKED;
 typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t;
@@ -993,7 +993,7 @@ typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t;
 struct grub_efi_protocol_device_path
 {
   grub_efi_device_path_t header;
-  grub_guid_t guid;
+  grub_packed_guid_t guid;
 } GRUB_PACKED;
 typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t;
 
@@ -1002,7 +1002,7 @@ typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t;
 struct grub_efi_piwg_device_path
 {
   grub_efi_device_path_t header;
-  grub_guid_t guid;
+  grub_packed_guid_t guid;
 } GRUB_PACKED;
 typedef struct grub_efi_piwg_device_path grub_efi_piwg_device_path_t;
 
@@ -1287,7 +1287,7 @@ struct grub_efi_boot_services
 
   grub_efi_status_t
   (__grub_efi_api *protocols_per_handle) (grub_efi_handle_t handle,
-                                         grub_guid_t ***protocol_buffer,
+                                         grub_packed_guid_t ***protocol_buffer,
                                          grub_efi_uintn_t *protocol_buffer_count);
 
   grub_efi_status_t
@@ -1386,7 +1386,7 @@ typedef struct grub_efi_runtime_services grub_efi_runtime_services_t;
 
 struct grub_efi_configuration_table
 {
-  grub_guid_t vendor_guid;
+  grub_packed_guid_t vendor_guid;
   void *vendor_table;
 } GRUB_PACKED;
 typedef struct grub_efi_configuration_table grub_efi_configuration_table_t;
index caf0b505f880591b771e5fb4c80c1e7049a12849..d6a868e94ad0c2eeda0af99f14a8d134fcdb63ed 100644 (file)
@@ -183,13 +183,13 @@ struct grub_efiemu_configuration_table
 };
 struct grub_efiemu_configuration_table32
 {
-  grub_guid_t vendor_guid;
+  grub_packed_guid_t vendor_guid;
   grub_efi_uint32_t vendor_table;
 } GRUB_PACKED;
 typedef struct grub_efiemu_configuration_table32 grub_efiemu_configuration_table32_t;
 struct grub_efiemu_configuration_table64
 {
-  grub_guid_t vendor_guid;
+  grub_packed_guid_t vendor_guid;
   grub_efi_uint64_t vendor_table;
 } GRUB_PACKED;
 typedef struct grub_efiemu_configuration_table64 grub_efiemu_configuration_table64_t;
index c9ad9fdfaf12233dc158430fce36209647c84d70..2ff42984545c3bdf873c2f989f9d1ccd3b5db2d1 100644 (file)
@@ -29,7 +29,7 @@ struct grub_efiemu_ptv_rel
 
 struct efi_variable
 {
-  grub_guid_t guid;
+  grub_packed_guid_t guid;
   grub_uint32_t namelen;
   grub_uint32_t size;
   grub_efi_uint32_t attributes;
index 45536a661f48990f0cddd7e316230543e3e73213..064066e2e18449ef90216aff43591dd63286e387 100644 (file)
@@ -376,7 +376,16 @@ struct grub_guid
   grub_uint16_t data2;
   grub_uint16_t data3;
   grub_uint8_t data4[8];
-} GRUB_PACKED;
+} __attribute__ ((aligned(4)));
 typedef struct grub_guid grub_guid_t;
 
+struct grub_packed_guid
+{
+  grub_uint32_t data1;
+  grub_uint16_t data2;
+  grub_uint16_t data3;
+  grub_uint8_t data4[8];
+} GRUB_PACKED;
+typedef struct grub_packed_guid grub_packed_guid_t;
+
 #endif /* ! GRUB_TYPES_HEADER */