grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SECURITY PATCH 108/117] util/mkimage: Refactor section setup to use a h


From: Daniel Kiper
Subject: [SECURITY PATCH 108/117] util/mkimage: Refactor section setup to use a helper
Date: Tue, 2 Mar 2021 19:01:55 +0100

From: Peter Jones <pjones@redhat.com>

Add a init_pe_section() helper function to setup PE sections. This makes
the code simpler and easier to read.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 util/mkimage.c | 141 +++++++++++++++++++++++++++++++--------------------------
 1 file changed, 76 insertions(+), 65 deletions(-)

diff --git a/util/mkimage.c b/util/mkimage.c
index 853a52179..8b475a691 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -817,6 +817,38 @@ grub_install_get_image_targets_string (void)
 }
 
 /*
+ * The image_target parameter is used by the grub_host_to_target32() macro.
+ */
+static struct grub_pe32_section_table *
+init_pe_section(const struct grub_install_image_target_desc *image_target,
+               struct grub_pe32_section_table *section,
+               const char * const name,
+               grub_uint32_t *vma, grub_uint32_t vsz, grub_uint32_t valign,
+               grub_uint32_t *rda, grub_uint32_t rsz,
+               grub_uint32_t characteristics)
+{
+  size_t len = strlen (name);
+
+  if (len > sizeof (section->name))
+    grub_util_error (_("section name %s length is bigger than %lu"),
+                    name, (unsigned long) sizeof (section->name));
+
+  memcpy (section->name, name, len);
+
+  section->virtual_address = grub_host_to_target32 (*vma);
+  section->virtual_size = grub_host_to_target32 (vsz);
+  (*vma) = ALIGN_UP (*vma + vsz, valign);
+
+  section->raw_data_offset = grub_host_to_target32 (*rda);
+  section->raw_data_size = grub_host_to_target32 (rsz);
+  (*rda) = ALIGN_UP (*rda + rsz, GRUB_PE32_FILE_ALIGNMENT);
+
+  section->characteristics = grub_host_to_target32 (characteristics);
+
+  return section + 1;
+}
+
+/*
  * tmp_ is just here so the compiler knows we'll never derefernce a NULL.
  * It should get fully optimized away.
  */
@@ -1257,17 +1289,13 @@ grub_install_generate_image (const char *dir, const 
char *prefix,
       break;
     case IMAGE_EFI:
       {
-       void *pe_img;
-       grub_uint8_t *header;
-       void *sections;
+       char *pe_img, *header;
+       struct grub_pe32_section_table *section;
        size_t scn_size;
-       size_t pe_size;
+       grub_uint32_t vma, raw_data;
+       size_t pe_size, header_size;
        struct grub_pe32_coff_header *c;
-       struct grub_pe32_section_table *text_section, *data_section;
-       struct grub_pe32_section_table *mods_section, *reloc_section;
        static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
-       int header_size;
-       int reloc_addr;
        struct grub_pe32_optional_header *o32 = NULL;
        struct grub_pe64_optional_header *o64 = NULL;
 
@@ -1276,17 +1304,12 @@ grub_install_generate_image (const char *dir, const 
char *prefix,
        else
          header_size = EFI64_HEADER_SIZE;
 
-       reloc_addr = ALIGN_UP (header_size + core_size,
-                              GRUB_PE32_FILE_ALIGNMENT);
+       vma = raw_data = header_size;
+       pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) +
+          ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT);
+       header = pe_img = xcalloc (1, pe_size);
 
-       pe_size = ALIGN_UP (reloc_addr + layout.reloc_size,
-                           GRUB_PE32_FILE_ALIGNMENT);
-       pe_img = xmalloc (reloc_addr + layout.reloc_size);
-       memset (pe_img, 0, header_size);
-       memcpy ((char *) pe_img + header_size, core_img, core_size);
-       memset ((char *) pe_img + header_size + core_size, 0, reloc_addr - 
(header_size + core_size));
-       memcpy ((char *) pe_img + reloc_addr, layout.reloc_section, 
layout.reloc_size);
-       header = pe_img;
+       memcpy (pe_img + raw_data, core_img, core_size);
 
        /* The magic.  */
        memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE);
@@ -1319,18 +1342,17 @@ grub_install_generate_image (const char *dir, const 
char *prefix,
            o32->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
            o32->data_base = grub_host_to_target32 (header_size + 
layout.exec_size);
 
-           sections = o32 + 1;
+           section = (struct grub_pe32_section_table *)(o32 + 1);
          }
        else
          {
            c->optional_header_size = grub_host_to_target16 (sizeof (struct 
grub_pe64_optional_header));
-
            o64 = (struct grub_pe64_optional_header *)
                  (header + GRUB_PE32_MSDOS_STUB_SIZE + 
GRUB_PE32_SIGNATURE_SIZE +
                    sizeof (struct grub_pe32_coff_header));
            o64->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
 
-           sections = o64 + 1;
+           section = (struct grub_pe32_section_table *)(o64 + 1);
          }
 
        PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
@@ -1350,58 +1372,47 @@ grub_install_generate_image (const char *dir, const 
char *prefix,
        PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 
(GRUB_PE32_NUM_DATA_DIRECTORIES);
 
        /* The sections.  */
-       PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size);
+       PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (vma);
        PE_OHDR (o32, o64, code_size) = grub_host_to_target32 
(layout.exec_size);
-       text_section = sections;
-       strcpy (text_section->name, ".text");
-       text_section->virtual_size = grub_host_to_target32 (layout.exec_size);
-       text_section->virtual_address = grub_host_to_target32 (header_size);
-       text_section->raw_data_size = grub_host_to_target32 (layout.exec_size);
-       text_section->raw_data_offset = grub_host_to_target32 (header_size);
-       text_section->characteristics = grub_cpu_to_le32_compile_time (
-                                                 GRUB_PE32_SCN_CNT_CODE
-                                               | GRUB_PE32_SCN_MEM_EXECUTE
-                                               | GRUB_PE32_SCN_MEM_READ);
+       section = init_pe_section (image_target, section, ".text",
+                                  &vma, layout.exec_size,
+                                  image_target->section_align,
+                                  &raw_data, layout.exec_size,
+                                  GRUB_PE32_SCN_CNT_CODE |
+                                  GRUB_PE32_SCN_MEM_EXECUTE |
+                                  GRUB_PE32_SCN_MEM_READ);
 
        scn_size = ALIGN_UP (layout.kernel_size - layout.exec_size, 
GRUB_PE32_FILE_ALIGNMENT);
        PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size +
                                                               ALIGN_UP 
(total_module_size,
                                                                         
GRUB_PE32_FILE_ALIGNMENT));
 
-       data_section = text_section + 1;
-       strcpy (data_section->name, ".data");
-       data_section->virtual_size = grub_host_to_target32 (layout.kernel_size 
- layout.exec_size);
-       data_section->virtual_address = grub_host_to_target32 (header_size + 
layout.exec_size);
-       data_section->raw_data_size = grub_host_to_target32 (layout.kernel_size 
- layout.exec_size);
-       data_section->raw_data_offset = grub_host_to_target32 (header_size + 
layout.exec_size);
-       data_section->characteristics
-         = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
-                             | GRUB_PE32_SCN_MEM_READ
-                             | GRUB_PE32_SCN_MEM_WRITE);
-    
-       mods_section = data_section + 1;
-       strcpy (mods_section->name, "mods");
-       mods_section->virtual_size = grub_host_to_target32 (reloc_addr - 
layout.kernel_size - header_size);
-       mods_section->virtual_address = grub_host_to_target32 (header_size + 
layout.kernel_size + layout.bss_size);
-       mods_section->raw_data_size = grub_host_to_target32 (reloc_addr - 
layout.kernel_size - header_size);
-       mods_section->raw_data_offset = grub_host_to_target32 (header_size + 
layout.kernel_size);
-       mods_section->characteristics
-         = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
-                             | GRUB_PE32_SCN_MEM_READ
-                             | GRUB_PE32_SCN_MEM_WRITE);
+       section = init_pe_section (image_target, section, ".data",
+                                  &vma, scn_size, image_target->section_align,
+                                  &raw_data, scn_size,
+                                  GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
+                                  GRUB_PE32_SCN_MEM_READ |
+                                  GRUB_PE32_SCN_MEM_WRITE);
+
+       scn_size = pe_size - layout.reloc_size - raw_data;
+       section = init_pe_section (image_target, section, "mods",
+                                  &vma, scn_size, image_target->section_align,
+                                  &raw_data, scn_size,
+                                  GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
+                                  GRUB_PE32_SCN_MEM_READ |
+                                  GRUB_PE32_SCN_MEM_WRITE);
+
+       scn_size = layout.reloc_size;
+       PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 
(vma);
+       PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 
(scn_size);
+       memcpy (pe_img + raw_data, layout.reloc_section, scn_size);
+       init_pe_section (image_target, section, ".reloc",
+                        &vma, scn_size, image_target->section_align,
+                        &raw_data, scn_size,
+                        GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
+                        GRUB_PE32_SCN_MEM_DISCARDABLE |
+                        GRUB_PE32_SCN_MEM_READ);
 
-       PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 
(reloc_addr);
-       PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 
(layout.reloc_size);
-       reloc_section = mods_section + 1;
-       strcpy (reloc_section->name, ".reloc");
-       reloc_section->virtual_size = grub_host_to_target32 (layout.reloc_size);
-       reloc_section->virtual_address = grub_host_to_target32 (reloc_addr + 
layout.bss_size);
-       reloc_section->raw_data_size = grub_host_to_target32 
(layout.reloc_size);
-       reloc_section->raw_data_offset = grub_host_to_target32 (reloc_addr);
-       reloc_section->characteristics
-         = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
-                             | GRUB_PE32_SCN_MEM_DISCARDABLE
-                             | GRUB_PE32_SCN_MEM_READ);
        free (core_img);
        core_img = pe_img;
        core_size = pe_size;
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]