efi/libstub/x86: Make loaded_image protocol handling mixed mode safe
authorArd Biesheuvel <ardb@kernel.org>
Fri, 14 Feb 2020 13:29:21 +0000 (14:29 +0100)
committerArd Biesheuvel <ardb@kernel.org>
Sun, 23 Feb 2020 20:59:42 +0000 (21:59 +0100)
Add the definitions and use the special wrapper so that the loaded_image
UEFI protocol can be safely used from mixed mode.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
drivers/firmware/efi/libstub/efi-stub-helper.c
drivers/firmware/efi/libstub/efistub.h
drivers/firmware/efi/libstub/x86-stub.c

index b1da58141a4dc31024784e124a02670687b4c9a8..9f34c72429397de01e65a4f4fd081775b05b883b 100644 (file)
@@ -171,8 +171,8 @@ char *efi_convert_cmdline(efi_loaded_image_t *image,
        const u16 *s2;
        u8 *s1 = NULL;
        unsigned long cmdline_addr = 0;
-       int load_options_chars = image->load_options_size / 2; /* UTF-16 */
-       const u16 *options = image->load_options;
+       int load_options_chars = efi_table_attr(image, load_options_size) / 2;
+       const u16 *options = efi_table_attr(image, load_options);
        int options_bytes = 0;  /* UTF-8 bytes */
        int options_chars = 0;  /* UTF-16 chars */
        efi_status_t status;
index 2e5e79edb4d76c85e8a2f3503ec29dc9f7aab103..6960e730f9907e9b15bb08fc5984e8f042138f5b 100644 (file)
@@ -308,20 +308,37 @@ union efi_graphics_output_protocol {
        } mixed_mode;
 };
 
-typedef struct {
-       u32                     revision;
-       efi_handle_t            parent_handle;
-       efi_system_table_t      *system_table;
-       efi_handle_t            device_handle;
-       void                    *file_path;
-       void                    *reserved;
-       u32                     load_options_size;
-       void                    *load_options;
-       void                    *image_base;
-       __aligned_u64           image_size;
-       unsigned int            image_code_type;
-       unsigned int            image_data_type;
-       efi_status_t            (__efiapi *unload)(efi_handle_t image_handle);
+typedef union {
+       struct {
+               u32                     revision;
+               efi_handle_t            parent_handle;
+               efi_system_table_t      *system_table;
+               efi_handle_t            device_handle;
+               void                    *file_path;
+               void                    *reserved;
+               u32                     load_options_size;
+               void                    *load_options;
+               void                    *image_base;
+               __aligned_u64           image_size;
+               unsigned int            image_code_type;
+               unsigned int            image_data_type;
+               efi_status_t            (__efiapi *unload)(efi_handle_t image_handle);
+       };
+       struct {
+               u32             revision;
+               u32             parent_handle;
+               u32             system_table;
+               u32             device_handle;
+               u32             file_path;
+               u32             reserved;
+               u32             load_options_size;
+               u32             load_options;
+               u32             image_base;
+               __aligned_u64   image_size;
+               u32             image_code_type;
+               u32             image_data_type;
+               u32             unload;
+       } mixed_mode;
 } efi_loaded_image_t;
 
 typedef struct {
index 7d4866471f86f0fa4da305af99219900e78b674b..ce0c3caa3087e182ea4947b72997254b17374cbc 100644 (file)
@@ -377,7 +377,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
                return status;
        }
 
-       hdr = &((struct boot_params *)image->image_base)->hdr;
+       hdr = &((struct boot_params *)efi_table_attr(image, image_base))->hdr;
        above4g = hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G;
 
        status = efi_allocate_pages(0x4000, (unsigned long *)&boot_params,
@@ -392,7 +392,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
        hdr = &boot_params->hdr;
 
        /* Copy the second sector to boot_params */
-       memcpy(&hdr->jump, image->image_base + 512, 512);
+       memcpy(&hdr->jump, efi_table_attr(image, image_base) + 512, 512);
 
        /*
         * Fill out some of the header fields ourselves because the