From: Peter Jones <pjo...@redhat.com>

In order to properly validate a loaded kernel's support for being loaded
without a writable stack or executable, we need to be able to properly
parse arbitrary PE headers.

Currently, pe32.h is written in such a way that the MS-DOS header that
tells us where to find the PE header in the binary can't be accessed.
Further, for some reason it calls the DOS MZ magic "GRUB_PE32_MAGIC".

This patch adds the structure for the DOS header, renames the DOS magic
define, and adds defines for the actual PE magic.

Signed-off-by: Peter Jones <pjo...@redhat.com>
(cherry picked from commit c850db5c0478c8328ebdd48ee8cce02995d4ead0)
Signed-off-by: Jan Setje-Eilers <jan.setjeeil...@oracle.com>

 Conflicts:
        grub-core/loader/arm64/linux.c  (deleted)
        include/grub/efi/pe32.h         (fixup)

Signed-off-by: Mate Kukri <mate.ku...@canonical.com>
---
 include/grub/efi/pe32.h | 98 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 92 insertions(+), 6 deletions(-)

diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
index 4e6e9d254..20db6be19 100644
--- a/include/grub/efi/pe32.h
+++ b/include/grub/efi/pe32.h
@@ -48,6 +48,29 @@
 
 #define GRUB_PE32_MAGIC                        0x5a4d
 
+struct grub_dos_header
+{
+  grub_uint16_t magic;
+  grub_uint16_t cblp;
+  grub_uint16_t cp;
+  grub_uint16_t crlc;
+  grub_uint16_t cparhdr;
+  grub_uint16_t minalloc;
+  grub_uint16_t maxalloc;
+  grub_uint16_t ss;
+  grub_uint16_t sp;
+  grub_uint16_t csum;
+  grub_uint16_t ip;
+  grub_uint16_t cs;
+  grub_uint16_t lfarlc;
+  grub_uint16_t ovno;
+  grub_uint16_t res0[4];
+  grub_uint16_t oemid;
+  grub_uint16_t oeminfo;
+  grub_uint16_t res1[10];
+  grub_uint32_t lfanew;
+};
+
 struct grub_msdos_image_header
 {
   /* This is always 'MZ'. (GRUB_PE32_MAGIC)  */
@@ -171,6 +194,8 @@ struct grub_pe32_optional_header
   struct grub_pe32_data_directory reserved_entry;
 };
 
+#define GRUB_PE32_NX_COMPAT 0x0100
+
 struct grub_pe64_optional_header
 {
   grub_uint16_t magic;
@@ -236,7 +261,11 @@ struct grub_pe64_optional_header
 struct grub_pe32_section_table
 {
   char name[8];
-  grub_uint32_t virtual_size;
+  union
+    {
+      grub_uint32_t physical_address;
+      grub_uint32_t virtual_size;
+    };
   grub_uint32_t virtual_address;
   grub_uint32_t raw_data_size;
   grub_uint32_t raw_data_offset;
@@ -247,12 +276,18 @@ struct grub_pe32_section_table
   grub_uint32_t characteristics;
 };
 
+#define GRUB_PE32_SCN_TYPE_NO_PAD              0x00000008
 #define GRUB_PE32_SCN_CNT_CODE                 0x00000020
 #define GRUB_PE32_SCN_CNT_INITIALIZED_DATA     0x00000040
-#define GRUB_PE32_SCN_MEM_DISCARDABLE          0x02000000
-#define GRUB_PE32_SCN_MEM_EXECUTE              0x20000000
-#define GRUB_PE32_SCN_MEM_READ                 0x40000000
-#define GRUB_PE32_SCN_MEM_WRITE                        0x80000000
+#define GRUB_PE32_SCN_CNT_UNINITIALIZED_DATA   0x00000080
+#define GRUB_PE32_SCN_LNK_OTHER                        0x00000100
+#define GRUB_PE32_SCN_LNK_INFO                 0x00000200
+#define GRUB_PE32_SCN_LNK_REMOVE               0x00000800
+#define GRUB_PE32_SCN_LNK_COMDAT               0x00001000
+#define GRUB_PE32_SCN_GPREL                    0x00008000
+#define GRUB_PE32_SCN_MEM_16BIT                        0x00020000
+#define GRUB_PE32_SCN_MEM_LOCKED               0x00040000
+#define GRUB_PE32_SCN_MEM_PRELOAD              0x00080000
 
 #define GRUB_PE32_SCN_ALIGN_1BYTES             0x00100000
 #define GRUB_PE32_SCN_ALIGN_2BYTES             0x00200000
@@ -261,11 +296,28 @@ struct grub_pe32_section_table
 #define GRUB_PE32_SCN_ALIGN_16BYTES            0x00500000
 #define GRUB_PE32_SCN_ALIGN_32BYTES            0x00600000
 #define GRUB_PE32_SCN_ALIGN_64BYTES            0x00700000
+#define GRUB_PE32_SCN_ALIGN_128BYTES           0x00800000
+#define GRUB_PE32_SCN_ALIGN_256BYTES           0x00900000
+#define GRUB_PE32_SCN_ALIGN_512BYTES           0x00A00000
+#define GRUB_PE32_SCN_ALIGN_1024BYTES          0x00B00000
+#define GRUB_PE32_SCN_ALIGN_2048BYTES          0x00C00000
+#define GRUB_PE32_SCN_ALIGN_4096BYTES          0x00D00000
+#define GRUB_PE32_SCN_ALIGN_8192BYTES          0x00E00000
 
 #define GRUB_PE32_SCN_ALIGN_SHIFT              20
 #define GRUB_PE32_SCN_ALIGN_MASK               7
 
-#define GRUB_PE32_SIGNATURE_SIZE 4
+#define GRUB_PE32_SCN_LNK_NRELOC_OVFL          0x01000000
+#define GRUB_PE32_SCN_MEM_DISCARDABLE          0x02000000
+#define GRUB_PE32_SCN_MEM_NOT_CACHED           0x04000000
+#define GRUB_PE32_SCN_MEM_NOT_PAGED            0x08000000
+#define GRUB_PE32_SCN_MEM_SHARED               0x10000000
+#define GRUB_PE32_SCN_MEM_EXECUTE              0x20000000
+#define GRUB_PE32_SCN_MEM_READ                 0x40000000
+#define GRUB_PE32_SCN_MEM_WRITE                        0x80000000
+
+#define GRUB_PE32_SIGNATURE_SIZE               4
+#define GRUB_PE32_SIGNATURE                    "PE\0\0"
 
 #if GRUB_TARGET_SIZEOF_VOID_P == 8
 #define GRUB_PE32_NATIVE_MAGIC                 GRUB_PE32_PE64_MAGIC
@@ -290,6 +342,40 @@ struct grub_pe_image_header
 #endif
 };
 
+struct grub_pe32_header
+{
+  /* This should be filled in with GRUB_PE32_MSDOS_STUB.  */
+  grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE];
+
+  /* This is always PE\0\0.  */
+  char signature[GRUB_PE32_SIGNATURE_SIZE];
+
+  /* The COFF file header.  */
+  struct grub_pe32_coff_header coff_header;
+
+#if GRUB_TARGET_SIZEOF_VOID_P == 8
+  /* The Optional header.  */
+  struct grub_pe64_optional_header optional_header;
+#else
+  /* The Optional header.  */
+  struct grub_pe32_optional_header optional_header;
+#endif
+};
+
+struct grub_pe32_header_32
+{
+  char signature[GRUB_PE32_SIGNATURE_SIZE];
+  struct grub_pe32_coff_header coff_header;
+  struct grub_pe32_optional_header optional_header;
+};
+
+struct grub_pe32_header_64
+{
+  char signature[GRUB_PE32_SIGNATURE_SIZE];
+  struct grub_pe32_coff_header coff_header;
+  struct grub_pe64_optional_header optional_header;
+};
+
 struct grub_pe32_fixup_block
 {
   grub_uint32_t page_rva;
-- 
2.39.2


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to