* [PATCH 0/7] arm64: efi: PE/COFF cleanup/hardening
@ 2017-02-06 16:24 ` Ard Biesheuvel
0 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel
This cleans up the PE/COFF EFI header, by taking some of Mark's patches
and use them to replace open coded constants with symbolic ones, and
remove incorrect values or unused sections.
Finally, it updates the section layout so that the kernel Image can be
mapped in a way that does not require setting RWX permissions anywhere.
Note that this is currently not a huge win, given that most current UEFI
implementations map all of RAM RWX by default, but this is finally gaining
some attention, and work is underway to make the PE/COFF loader in EDK2
adhere to the section permissions, which would also allow the RAM mapping
to default to non-executable. Work in progress nonetheless...
Ard Biesheuvel (5):
arm64: efi: move EFI header and related data to a separate .S file
arm64: efi: ensure that the PE/COFF header pointer appears at offset
0x3c
arm64: efi: remove pointless dummy .reloc section
arm64: efi: replace open coded constants with symbolic ones
arm64: efi: split Image code and data into separate PE/COFF sections
Mark Rutland (2):
include: pe.h: allow for use in assembly
include: pe.h: add some missing definitions
arch/arm64/kernel/efi-header.S | 178 ++++++++++++++++++++
arch/arm64/kernel/head.S | 176 +------------------
arch/arm64/kernel/vmlinux.lds.S | 5 +
include/linux/pe.h | 177 +++++++++----------
4 files changed, 280 insertions(+), 256 deletions(-)
create mode 100644 arch/arm64/kernel/efi-header.S
--
2.7.4
^ permalink raw reply [flat|nested] 32+ messages in thread
* [kernel-hardening] [PATCH 0/7] arm64: efi: PE/COFF cleanup/hardening
@ 2017-02-06 16:24 ` Ard Biesheuvel
0 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel, will.deacon, catalin.marinas, mark.rutland
Cc: labbott, kernel-hardening, leif.lindholm, pjones, Ard Biesheuvel
This cleans up the PE/COFF EFI header, by taking some of Mark's patches
and use them to replace open coded constants with symbolic ones, and
remove incorrect values or unused sections.
Finally, it updates the section layout so that the kernel Image can be
mapped in a way that does not require setting RWX permissions anywhere.
Note that this is currently not a huge win, given that most current UEFI
implementations map all of RAM RWX by default, but this is finally gaining
some attention, and work is underway to make the PE/COFF loader in EDK2
adhere to the section permissions, which would also allow the RAM mapping
to default to non-executable. Work in progress nonetheless...
Ard Biesheuvel (5):
arm64: efi: move EFI header and related data to a separate .S file
arm64: efi: ensure that the PE/COFF header pointer appears at offset
0x3c
arm64: efi: remove pointless dummy .reloc section
arm64: efi: replace open coded constants with symbolic ones
arm64: efi: split Image code and data into separate PE/COFF sections
Mark Rutland (2):
include: pe.h: allow for use in assembly
include: pe.h: add some missing definitions
arch/arm64/kernel/efi-header.S | 178 ++++++++++++++++++++
arch/arm64/kernel/head.S | 176 +------------------
arch/arm64/kernel/vmlinux.lds.S | 5 +
include/linux/pe.h | 177 +++++++++----------
4 files changed, 280 insertions(+), 256 deletions(-)
create mode 100644 arch/arm64/kernel/efi-header.S
--
2.7.4
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 1/7] include: pe.h: allow for use in assembly
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 16:24 ` Ard Biesheuvel
-1 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel
From: Mark Rutland <mark.rutland@arm.com>
Some of the definitions in include/linux/pe.h would be useful for the
EFI stub headers, where values are currently open-coded. Unfortunately
they cannot be used as some structures are also defined in pe.h without
!__ASSEMBLY__ guards.
This patch moves the structure definitions into an #ifdef __ASSEMBLY__
block, so that the common value definitions can be used from assembly.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
include/linux/pe.h | 174 ++++++++++----------
1 file changed, 89 insertions(+), 85 deletions(-)
diff --git a/include/linux/pe.h b/include/linux/pe.h
index e170b95e763b..a8a594117df3 100644
--- a/include/linux/pe.h
+++ b/include/linux/pe.h
@@ -23,34 +23,6 @@
#define MZ_MAGIC 0x5a4d /* "MZ" */
-struct mz_hdr {
- uint16_t magic; /* MZ_MAGIC */
- uint16_t lbsize; /* size of last used block */
- uint16_t blocks; /* pages in file, 0x3 */
- uint16_t relocs; /* relocations */
- uint16_t hdrsize; /* header size in "paragraphs" */
- uint16_t min_extra_pps; /* .bss */
- uint16_t max_extra_pps; /* runtime limit for the arena size */
- uint16_t ss; /* relative stack segment */
- uint16_t sp; /* initial %sp register */
- uint16_t checksum; /* word checksum */
- uint16_t ip; /* initial %ip register */
- uint16_t cs; /* initial %cs relative to load segment */
- uint16_t reloc_table_offset; /* offset of the first relocation */
- uint16_t overlay_num; /* overlay number. set to 0. */
- uint16_t reserved0[4]; /* reserved */
- uint16_t oem_id; /* oem identifier */
- uint16_t oem_info; /* oem specific */
- uint16_t reserved1[10]; /* reserved */
- uint32_t peaddr; /* address of pe header */
- char message[64]; /* message to print */
-};
-
-struct mz_reloc {
- uint16_t offset;
- uint16_t segment;
-};
-
#define PE_MAGIC 0x00004550 /* "PE\0\0" */
#define PE_OPT_MAGIC_PE32 0x010b
#define PE_OPT_MAGIC_PE32_ROM 0x0107
@@ -98,17 +70,6 @@ struct mz_reloc {
#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
-struct pe_hdr {
- uint32_t magic; /* PE magic */
- uint16_t machine; /* machine type */
- uint16_t sections; /* number of sections */
- uint32_t timestamp; /* time_t */
- uint32_t symbol_table; /* symbol table offset */
- uint32_t symbols; /* number of symbols */
- uint16_t opt_hdr_size; /* size of optional header */
- uint16_t flags; /* flags */
-};
-
#define IMAGE_FILE_OPT_ROM_MAGIC 0x107
#define IMAGE_FILE_OPT_PE32_MAGIC 0x10b
#define IMAGE_FILE_OPT_PE32_PLUS_MAGIC 0x20b
@@ -134,6 +95,93 @@ struct pe_hdr {
#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
+/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
+#define IMAGE_SCN_RESERVED_0 0x00000001
+#define IMAGE_SCN_RESERVED_1 0x00000002
+#define IMAGE_SCN_RESERVED_2 0x00000004
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
+#define IMAGE_SCN_RESERVED_3 0x00000010
+#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
+#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
+#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
+#define IMAGE_SCN_RESERVED_4 0x00000400
+#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
+#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
+#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
+#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
+#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
+/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
+#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
+#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
+#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
+#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
+/* and here they just stuck a 1-byte integer in the middle of a bitfield */
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
+#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
+#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
+#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
+#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
+#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
+#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
+#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
+#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
+#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
+#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
+
+#ifndef __ASSEMBLY__
+
+struct mz_hdr {
+ uint16_t magic; /* MZ_MAGIC */
+ uint16_t lbsize; /* size of last used block */
+ uint16_t blocks; /* pages in file, 0x3 */
+ uint16_t relocs; /* relocations */
+ uint16_t hdrsize; /* header size in "paragraphs" */
+ uint16_t min_extra_pps; /* .bss */
+ uint16_t max_extra_pps; /* runtime limit for the arena size */
+ uint16_t ss; /* relative stack segment */
+ uint16_t sp; /* initial %sp register */
+ uint16_t checksum; /* word checksum */
+ uint16_t ip; /* initial %ip register */
+ uint16_t cs; /* initial %cs relative to load segment */
+ uint16_t reloc_table_offset; /* offset of the first relocation */
+ uint16_t overlay_num; /* overlay number. set to 0. */
+ uint16_t reserved0[4]; /* reserved */
+ uint16_t oem_id; /* oem identifier */
+ uint16_t oem_info; /* oem specific */
+ uint16_t reserved1[10]; /* reserved */
+ uint32_t peaddr; /* address of pe header */
+ char message[64]; /* message to print */
+};
+
+struct mz_reloc {
+ uint16_t offset;
+ uint16_t segment;
+};
+
+struct pe_hdr {
+ uint32_t magic; /* PE magic */
+ uint16_t machine; /* machine type */
+ uint16_t sections; /* number of sections */
+ uint32_t timestamp; /* time_t */
+ uint32_t symbol_table; /* symbol table offset */
+ uint32_t symbols; /* number of symbols */
+ uint16_t opt_hdr_size; /* size of optional header */
+ uint16_t flags; /* flags */
+};
+
/* the fact that pe32 isn't padded where pe32+ is 64-bit means union won't
* work right. vomit. */
struct pe32_opt_hdr {
@@ -243,52 +291,6 @@ struct section_header {
uint32_t flags;
};
-/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
-#define IMAGE_SCN_RESERVED_0 0x00000001
-#define IMAGE_SCN_RESERVED_1 0x00000002
-#define IMAGE_SCN_RESERVED_2 0x00000004
-#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
-#define IMAGE_SCN_RESERVED_3 0x00000010
-#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
-#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
-#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
-#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
-#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
-#define IMAGE_SCN_RESERVED_4 0x00000400
-#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
-#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
-#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
-#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
-#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
-/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
-#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
-#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
-#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
-#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
-/* and here they just stuck a 1-byte integer in the middle of a bitfield */
-#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
-#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
-#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
-#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
-#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
-#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
-#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
-#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
-#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
-#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
-#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
-#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
-#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
-#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
-#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
-#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
-#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
-#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
-#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
-#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
-#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
-#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
-
enum x64_coff_reloc_type {
IMAGE_REL_AMD64_ABSOLUTE = 0,
IMAGE_REL_AMD64_ADDR64,
@@ -445,4 +447,6 @@ struct win_certificate {
uint16_t cert_type;
};
+#endif /* !__ASSEMBLY__ */
+
#endif /* __LINUX_PE_H */
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [kernel-hardening] [PATCH 1/7] include: pe.h: allow for use in assembly
@ 2017-02-06 16:24 ` Ard Biesheuvel
0 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel, will.deacon, catalin.marinas, mark.rutland
Cc: labbott, kernel-hardening, leif.lindholm, pjones
From: Mark Rutland <mark.rutland@arm.com>
Some of the definitions in include/linux/pe.h would be useful for the
EFI stub headers, where values are currently open-coded. Unfortunately
they cannot be used as some structures are also defined in pe.h without
!__ASSEMBLY__ guards.
This patch moves the structure definitions into an #ifdef __ASSEMBLY__
block, so that the common value definitions can be used from assembly.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
include/linux/pe.h | 174 ++++++++++----------
1 file changed, 89 insertions(+), 85 deletions(-)
diff --git a/include/linux/pe.h b/include/linux/pe.h
index e170b95e763b..a8a594117df3 100644
--- a/include/linux/pe.h
+++ b/include/linux/pe.h
@@ -23,34 +23,6 @@
#define MZ_MAGIC 0x5a4d /* "MZ" */
-struct mz_hdr {
- uint16_t magic; /* MZ_MAGIC */
- uint16_t lbsize; /* size of last used block */
- uint16_t blocks; /* pages in file, 0x3 */
- uint16_t relocs; /* relocations */
- uint16_t hdrsize; /* header size in "paragraphs" */
- uint16_t min_extra_pps; /* .bss */
- uint16_t max_extra_pps; /* runtime limit for the arena size */
- uint16_t ss; /* relative stack segment */
- uint16_t sp; /* initial %sp register */
- uint16_t checksum; /* word checksum */
- uint16_t ip; /* initial %ip register */
- uint16_t cs; /* initial %cs relative to load segment */
- uint16_t reloc_table_offset; /* offset of the first relocation */
- uint16_t overlay_num; /* overlay number. set to 0. */
- uint16_t reserved0[4]; /* reserved */
- uint16_t oem_id; /* oem identifier */
- uint16_t oem_info; /* oem specific */
- uint16_t reserved1[10]; /* reserved */
- uint32_t peaddr; /* address of pe header */
- char message[64]; /* message to print */
-};
-
-struct mz_reloc {
- uint16_t offset;
- uint16_t segment;
-};
-
#define PE_MAGIC 0x00004550 /* "PE\0\0" */
#define PE_OPT_MAGIC_PE32 0x010b
#define PE_OPT_MAGIC_PE32_ROM 0x0107
@@ -98,17 +70,6 @@ struct mz_reloc {
#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
-struct pe_hdr {
- uint32_t magic; /* PE magic */
- uint16_t machine; /* machine type */
- uint16_t sections; /* number of sections */
- uint32_t timestamp; /* time_t */
- uint32_t symbol_table; /* symbol table offset */
- uint32_t symbols; /* number of symbols */
- uint16_t opt_hdr_size; /* size of optional header */
- uint16_t flags; /* flags */
-};
-
#define IMAGE_FILE_OPT_ROM_MAGIC 0x107
#define IMAGE_FILE_OPT_PE32_MAGIC 0x10b
#define IMAGE_FILE_OPT_PE32_PLUS_MAGIC 0x20b
@@ -134,6 +95,93 @@ struct pe_hdr {
#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
+/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
+#define IMAGE_SCN_RESERVED_0 0x00000001
+#define IMAGE_SCN_RESERVED_1 0x00000002
+#define IMAGE_SCN_RESERVED_2 0x00000004
+#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
+#define IMAGE_SCN_RESERVED_3 0x00000010
+#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
+#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
+#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
+#define IMAGE_SCN_RESERVED_4 0x00000400
+#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
+#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
+#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
+#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
+#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
+/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
+#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
+#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
+#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
+#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
+/* and here they just stuck a 1-byte integer in the middle of a bitfield */
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
+#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
+#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
+#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
+#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
+#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
+#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
+#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
+#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
+#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
+#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
+
+#ifndef __ASSEMBLY__
+
+struct mz_hdr {
+ uint16_t magic; /* MZ_MAGIC */
+ uint16_t lbsize; /* size of last used block */
+ uint16_t blocks; /* pages in file, 0x3 */
+ uint16_t relocs; /* relocations */
+ uint16_t hdrsize; /* header size in "paragraphs" */
+ uint16_t min_extra_pps; /* .bss */
+ uint16_t max_extra_pps; /* runtime limit for the arena size */
+ uint16_t ss; /* relative stack segment */
+ uint16_t sp; /* initial %sp register */
+ uint16_t checksum; /* word checksum */
+ uint16_t ip; /* initial %ip register */
+ uint16_t cs; /* initial %cs relative to load segment */
+ uint16_t reloc_table_offset; /* offset of the first relocation */
+ uint16_t overlay_num; /* overlay number. set to 0. */
+ uint16_t reserved0[4]; /* reserved */
+ uint16_t oem_id; /* oem identifier */
+ uint16_t oem_info; /* oem specific */
+ uint16_t reserved1[10]; /* reserved */
+ uint32_t peaddr; /* address of pe header */
+ char message[64]; /* message to print */
+};
+
+struct mz_reloc {
+ uint16_t offset;
+ uint16_t segment;
+};
+
+struct pe_hdr {
+ uint32_t magic; /* PE magic */
+ uint16_t machine; /* machine type */
+ uint16_t sections; /* number of sections */
+ uint32_t timestamp; /* time_t */
+ uint32_t symbol_table; /* symbol table offset */
+ uint32_t symbols; /* number of symbols */
+ uint16_t opt_hdr_size; /* size of optional header */
+ uint16_t flags; /* flags */
+};
+
/* the fact that pe32 isn't padded where pe32+ is 64-bit means union won't
* work right. vomit. */
struct pe32_opt_hdr {
@@ -243,52 +291,6 @@ struct section_header {
uint32_t flags;
};
-/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
-#define IMAGE_SCN_RESERVED_0 0x00000001
-#define IMAGE_SCN_RESERVED_1 0x00000002
-#define IMAGE_SCN_RESERVED_2 0x00000004
-#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
-#define IMAGE_SCN_RESERVED_3 0x00000010
-#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
-#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
-#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
-#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
-#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
-#define IMAGE_SCN_RESERVED_4 0x00000400
-#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
-#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
-#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
-#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
-#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
-/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
-#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
-#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
-#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
-#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
-/* and here they just stuck a 1-byte integer in the middle of a bitfield */
-#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
-#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
-#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
-#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
-#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
-#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
-#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
-#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
-#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
-#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
-#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
-#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
-#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
-#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
-#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
-#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
-#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
-#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
-#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
-#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
-#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
-#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
-
enum x64_coff_reloc_type {
IMAGE_REL_AMD64_ABSOLUTE = 0,
IMAGE_REL_AMD64_ADDR64,
@@ -445,4 +447,6 @@ struct win_certificate {
uint16_t cert_type;
};
+#endif /* !__ASSEMBLY__ */
+
#endif /* __LINUX_PE_H */
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 2/7] include: pe.h: add some missing definitions
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 16:24 ` Ard Biesheuvel
-1 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel
From: Mark Rutland <mark.rutland@arm.com>
Add the missing IMAGE_FILE_MACHINE_ARM64 and IMAGE_DEBUG_TYPE_CODEVIEW
definitions.
We'll need them for the arm64 EFI stub...
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
include/linux/pe.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/pe.h b/include/linux/pe.h
index a8a594117df3..143ce75be5f0 100644
--- a/include/linux/pe.h
+++ b/include/linux/pe.h
@@ -34,6 +34,7 @@
#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_FILE_MACHINE_ARM 0x01c0
#define IMAGE_FILE_MACHINE_ARMV7 0x01c4
+#define IMAGE_FILE_MACHINE_ARM64 0xaa64
#define IMAGE_FILE_MACHINE_EBC 0x0ebc
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_IA64 0x0200
@@ -141,6 +142,8 @@
#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
+#define IMAGE_DEBUG_TYPE_CODEVIEW 2
+
#ifndef __ASSEMBLY__
struct mz_hdr {
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [kernel-hardening] [PATCH 2/7] include: pe.h: add some missing definitions
@ 2017-02-06 16:24 ` Ard Biesheuvel
0 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel, will.deacon, catalin.marinas, mark.rutland
Cc: labbott, kernel-hardening, leif.lindholm, pjones
From: Mark Rutland <mark.rutland@arm.com>
Add the missing IMAGE_FILE_MACHINE_ARM64 and IMAGE_DEBUG_TYPE_CODEVIEW
definitions.
We'll need them for the arm64 EFI stub...
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
include/linux/pe.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/pe.h b/include/linux/pe.h
index a8a594117df3..143ce75be5f0 100644
--- a/include/linux/pe.h
+++ b/include/linux/pe.h
@@ -34,6 +34,7 @@
#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_FILE_MACHINE_ARM 0x01c0
#define IMAGE_FILE_MACHINE_ARMV7 0x01c4
+#define IMAGE_FILE_MACHINE_ARM64 0xaa64
#define IMAGE_FILE_MACHINE_EBC 0x0ebc
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_IA64 0x0200
@@ -141,6 +142,8 @@
#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
+#define IMAGE_DEBUG_TYPE_CODEVIEW 2
+
#ifndef __ASSEMBLY__
struct mz_hdr {
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 3/7] arm64: efi: move EFI header and related data to a separate .S file
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 16:24 ` Ard Biesheuvel
-1 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel
In preparation of yet another round of modifications to the PE/COFF
header, macroize it and move the definition into a separate source
file.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
| 182 ++++++++++++++++++++
arch/arm64/kernel/head.S | 171 +-----------------
2 files changed, 186 insertions(+), 167 deletions(-)
--git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
new file mode 100644
index 000000000000..8c8cd0a8192b
--- /dev/null
+++ b/arch/arm64/kernel/efi-header.S
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2013 - 2017 Linaro, Ltd.
+ * Copyright (C) 2013, 2014 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+ .macro __jmp, target
+#ifdef CONFIG_EFI
+ /*
+ * This add instruction has no meaningful effect except that
+ * its opcode forms the magic "MZ" signature required by UEFI.
+ */
+ add x13, x18, #0x16
+ b \target
+#else
+ b \target // branch to kernel start, magic
+ .long 0 // reserved
+#endif
+ .endm
+
+ .macro __EFI_HEADER
+#ifdef CONFIG_EFI
+ .long pe_header - _head // Offset to the PE header.
+#else
+ .word 0 // reserved
+#endif
+
+#ifdef CONFIG_EFI
+ .align 3
+pe_header:
+ .ascii "PE"
+ .short 0
+coff_header:
+ .short 0xaa64 // AArch64
+ .short 2 // nr_sections
+ .long 0 // TimeDateStamp
+ .long 0 // PointerToSymbolTable
+ .long 1 // NumberOfSymbols
+ .short section_table - optional_header // SizeOfOptionalHeader
+ .short 0x206 // Characteristics.
+ // IMAGE_FILE_DEBUG_STRIPPED |
+ // IMAGE_FILE_EXECUTABLE_IMAGE |
+ // IMAGE_FILE_LINE_NUMS_STRIPPED
+optional_header:
+ .short 0x20b // PE32+ format
+ .byte 0x02 // MajorLinkerVersion
+ .byte 0x14 // MinorLinkerVersion
+ .long _end - efi_header_end // SizeOfCode
+ .long 0 // SizeOfInitializedData
+ .long 0 // SizeOfUninitializedData
+ .long __efistub_entry - _head // AddressOfEntryPoint
+ .long efi_header_end - _head // BaseOfCode
+
+extra_header_fields:
+ .quad 0 // ImageBase
+ .long 0x1000 // SectionAlignment
+ .long PECOFF_FILE_ALIGNMENT // FileAlignment
+ .short 0 // MajorOperatingSystemVersion
+ .short 0 // MinorOperatingSystemVersion
+ .short 0 // MajorImageVersion
+ .short 0 // MinorImageVersion
+ .short 0 // MajorSubsystemVersion
+ .short 0 // MinorSubsystemVersion
+ .long 0 // Win32VersionValue
+
+ .long _end - _head // SizeOfImage
+
+ // Everything before the kernel image is considered part of the header
+ .long efi_header_end - _head // SizeOfHeaders
+ .long 0 // CheckSum
+ .short 0xa // Subsystem (EFI application)
+ .short 0 // DllCharacteristics
+ .quad 0 // SizeOfStackReserve
+ .quad 0 // SizeOfStackCommit
+ .quad 0 // SizeOfHeapReserve
+ .quad 0 // SizeOfHeapCommit
+ .long 0 // LoaderFlags
+ .long (section_table - .) / 8 // NumberOfRvaAndSizes
+
+ .quad 0 // ExportTable
+ .quad 0 // ImportTable
+ .quad 0 // ResourceTable
+ .quad 0 // ExceptionTable
+ .quad 0 // CertificationTable
+ .quad 0 // BaseRelocationTable
+
+#ifdef CONFIG_DEBUG_EFI
+ .long efi_debug_table - _head // DebugTable
+ .long efi_debug_table_size
+#endif
+
+ // Section table
+section_table:
+
+ /*
+ * The EFI application loader requires a relocation section
+ * because EFI applications must be relocatable. This is a
+ * dummy section as far as we are concerned.
+ */
+ .ascii ".reloc"
+ .byte 0
+ .byte 0 // end of 0 padding of section name
+ .long 0
+ .long 0
+ .long 0 // SizeOfRawData
+ .long 0 // PointerToRawData
+ .long 0 // PointerToRelocations
+ .long 0 // PointerToLineNumbers
+ .short 0 // NumberOfRelocations
+ .short 0 // NumberOfLineNumbers
+ .long 0x42100040 // Characteristics (section flags)
+
+
+ .ascii ".text"
+ .byte 0
+ .byte 0
+ .byte 0 // end of 0 padding of section name
+ .long _end - efi_header_end // VirtualSize
+ .long efi_header_end - _head // VirtualAddress
+ .long _edata - efi_header_end // SizeOfRawData
+ .long efi_header_end - _head // PointerToRawData
+
+ .long 0 // PointerToRelocations
+ .long 0 // PointerToLineNumbers
+ .short 0 // NumberOfRelocations
+ .short 0 // NumberOfLineNumbers
+ .long 0xe0500020 // Characteristics
+
+#ifdef CONFIG_DEBUG_EFI
+ /*
+ * The debug table is referenced via its Relative Virtual Address (RVA),
+ * which is only defined for those parts of the image that are covered
+ * by a section declaration. Since this header is not covered by any
+ * section, the debug table must be emitted elsewhere. So stick it in
+ * the .init.rodata section instead.
+ *
+ * Note that the EFI debug entry itself may legally have a zero RVA,
+ * which means we can simply put it right after the section headers.
+ */
+ __INITRODATA
+
+ .align 2
+efi_debug_table:
+ // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
+ .long 0 // Characteristics
+ .long 0 // TimeDateStamp
+ .short 0 // MajorVersion
+ .short 0 // MinorVersion
+ .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
+ .long efi_debug_entry_size // SizeOfData
+ .long 0 // RVA
+ .long efi_debug_entry - _head // FileOffset
+
+ .set efi_debug_table_size, . - efi_debug_table
+ .previous
+
+efi_debug_entry:
+ // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
+ .ascii "NB10" // Signature
+ .long 0 // Unknown
+ .long 0 // Unknown2
+ .long 0 // Unknown3
+
+ .asciz VMLINUX_PATH
+
+ .set efi_debug_entry_size, . - efi_debug_entry
+#endif
+
+ /*
+ * EFI will load .text onwards at the 4k section alignment
+ * described in the PE/COFF header. To ensure that instruction
+ * sequences using an adrp and a :lo12: immediate will function
+ * correctly at this alignment, we must ensure that .text is
+ * placed at a 4k boundary in the Image to begin with.
+ */
+ .align 12
+efi_header_end:
+#endif
+ .endm
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index c6cc82ec190b..aca9b184035a 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -42,6 +42,8 @@
#include <asm/thread_info.h>
#include <asm/virt.h>
+#include "efi-header.S"
+
#define __PHYS_OFFSET (KERNEL_START - TEXT_OFFSET)
#if (TEXT_OFFSET & 0xfff) != 0
@@ -72,17 +74,7 @@ _head:
/*
* DO NOT MODIFY. Image header expected by Linux boot-loaders.
*/
-#ifdef CONFIG_EFI
- /*
- * This add instruction has no meaningful effect except that
- * its opcode forms the magic "MZ" signature required by UEFI.
- */
- add x13, x18, #0x16
- b stext
-#else
- b stext // branch to kernel start, magic
- .long 0 // reserved
-#endif
+ __jmp stext // Executable code
le64sym _kernel_offset_le // Image load offset from start of RAM, little-endian
le64sym _kernel_size_le // Effective size of kernel image, little-endian
le64sym _kernel_flags_le // Informative flags, little-endian
@@ -93,163 +85,8 @@ _head:
.byte 0x52
.byte 0x4d
.byte 0x64
-#ifdef CONFIG_EFI
- .long pe_header - _head // Offset to the PE header.
-#else
- .word 0 // reserved
-#endif
-
-#ifdef CONFIG_EFI
- .align 3
-pe_header:
- .ascii "PE"
- .short 0
-coff_header:
- .short 0xaa64 // AArch64
- .short 2 // nr_sections
- .long 0 // TimeDateStamp
- .long 0 // PointerToSymbolTable
- .long 1 // NumberOfSymbols
- .short section_table - optional_header // SizeOfOptionalHeader
- .short 0x206 // Characteristics.
- // IMAGE_FILE_DEBUG_STRIPPED |
- // IMAGE_FILE_EXECUTABLE_IMAGE |
- // IMAGE_FILE_LINE_NUMS_STRIPPED
-optional_header:
- .short 0x20b // PE32+ format
- .byte 0x02 // MajorLinkerVersion
- .byte 0x14 // MinorLinkerVersion
- .long _end - efi_header_end // SizeOfCode
- .long 0 // SizeOfInitializedData
- .long 0 // SizeOfUninitializedData
- .long __efistub_entry - _head // AddressOfEntryPoint
- .long efi_header_end - _head // BaseOfCode
-
-extra_header_fields:
- .quad 0 // ImageBase
- .long 0x1000 // SectionAlignment
- .long PECOFF_FILE_ALIGNMENT // FileAlignment
- .short 0 // MajorOperatingSystemVersion
- .short 0 // MinorOperatingSystemVersion
- .short 0 // MajorImageVersion
- .short 0 // MinorImageVersion
- .short 0 // MajorSubsystemVersion
- .short 0 // MinorSubsystemVersion
- .long 0 // Win32VersionValue
-
- .long _end - _head // SizeOfImage
-
- // Everything before the kernel image is considered part of the header
- .long efi_header_end - _head // SizeOfHeaders
- .long 0 // CheckSum
- .short 0xa // Subsystem (EFI application)
- .short 0 // DllCharacteristics
- .quad 0 // SizeOfStackReserve
- .quad 0 // SizeOfStackCommit
- .quad 0 // SizeOfHeapReserve
- .quad 0 // SizeOfHeapCommit
- .long 0 // LoaderFlags
- .long (section_table - .) / 8 // NumberOfRvaAndSizes
-
- .quad 0 // ExportTable
- .quad 0 // ImportTable
- .quad 0 // ResourceTable
- .quad 0 // ExceptionTable
- .quad 0 // CertificationTable
- .quad 0 // BaseRelocationTable
-
-#ifdef CONFIG_DEBUG_EFI
- .long efi_debug_table - _head // DebugTable
- .long efi_debug_table_size
-#endif
-
- // Section table
-section_table:
- /*
- * The EFI application loader requires a relocation section
- * because EFI applications must be relocatable. This is a
- * dummy section as far as we are concerned.
- */
- .ascii ".reloc"
- .byte 0
- .byte 0 // end of 0 padding of section name
- .long 0
- .long 0
- .long 0 // SizeOfRawData
- .long 0 // PointerToRawData
- .long 0 // PointerToRelocations
- .long 0 // PointerToLineNumbers
- .short 0 // NumberOfRelocations
- .short 0 // NumberOfLineNumbers
- .long 0x42100040 // Characteristics (section flags)
-
-
- .ascii ".text"
- .byte 0
- .byte 0
- .byte 0 // end of 0 padding of section name
- .long _end - efi_header_end // VirtualSize
- .long efi_header_end - _head // VirtualAddress
- .long _edata - efi_header_end // SizeOfRawData
- .long efi_header_end - _head // PointerToRawData
-
- .long 0 // PointerToRelocations (0 for executables)
- .long 0 // PointerToLineNumbers (0 for executables)
- .short 0 // NumberOfRelocations (0 for executables)
- .short 0 // NumberOfLineNumbers (0 for executables)
- .long 0xe0500020 // Characteristics (section flags)
-
-#ifdef CONFIG_DEBUG_EFI
- /*
- * The debug table is referenced via its Relative Virtual Address (RVA),
- * which is only defined for those parts of the image that are covered
- * by a section declaration. Since this header is not covered by any
- * section, the debug table must be emitted elsewhere. So stick it in
- * the .init.rodata section instead.
- *
- * Note that the EFI debug entry itself may legally have a zero RVA,
- * which means we can simply put it right after the section headers.
- */
- __INITRODATA
-
- .align 2
-efi_debug_table:
- // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
- .long 0 // Characteristics
- .long 0 // TimeDateStamp
- .short 0 // MajorVersion
- .short 0 // MinorVersion
- .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
- .long efi_debug_entry_size // SizeOfData
- .long 0 // RVA
- .long efi_debug_entry - _head // FileOffset
-
- .set efi_debug_table_size, . - efi_debug_table
- .previous
-
-efi_debug_entry:
- // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
- .ascii "NB10" // Signature
- .long 0 // Unknown
- .long 0 // Unknown2
- .long 0 // Unknown3
-
- .asciz VMLINUX_PATH
-
- .set efi_debug_entry_size, . - efi_debug_entry
-#endif
-
- /*
- * EFI will load .text onwards at the 4k section alignment
- * described in the PE/COFF header. To ensure that instruction
- * sequences using an adrp and a :lo12: immediate will function
- * correctly at this alignment, we must ensure that .text is
- * placed at a 4k boundary in the Image to begin with.
- */
- .align 12
-efi_header_end:
-#endif
+ __EFI_HEADER
__INIT
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [kernel-hardening] [PATCH 3/7] arm64: efi: move EFI header and related data to a separate .S file
@ 2017-02-06 16:24 ` Ard Biesheuvel
0 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel, will.deacon, catalin.marinas, mark.rutland
Cc: labbott, kernel-hardening, leif.lindholm, pjones, Ard Biesheuvel
In preparation of yet another round of modifications to the PE/COFF
header, macroize it and move the definition into a separate source
file.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
| 182 ++++++++++++++++++++
arch/arm64/kernel/head.S | 171 +-----------------
2 files changed, 186 insertions(+), 167 deletions(-)
--git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
new file mode 100644
index 000000000000..8c8cd0a8192b
--- /dev/null
+++ b/arch/arm64/kernel/efi-header.S
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2013 - 2017 Linaro, Ltd.
+ * Copyright (C) 2013, 2014 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+ .macro __jmp, target
+#ifdef CONFIG_EFI
+ /*
+ * This add instruction has no meaningful effect except that
+ * its opcode forms the magic "MZ" signature required by UEFI.
+ */
+ add x13, x18, #0x16
+ b \target
+#else
+ b \target // branch to kernel start, magic
+ .long 0 // reserved
+#endif
+ .endm
+
+ .macro __EFI_HEADER
+#ifdef CONFIG_EFI
+ .long pe_header - _head // Offset to the PE header.
+#else
+ .word 0 // reserved
+#endif
+
+#ifdef CONFIG_EFI
+ .align 3
+pe_header:
+ .ascii "PE"
+ .short 0
+coff_header:
+ .short 0xaa64 // AArch64
+ .short 2 // nr_sections
+ .long 0 // TimeDateStamp
+ .long 0 // PointerToSymbolTable
+ .long 1 // NumberOfSymbols
+ .short section_table - optional_header // SizeOfOptionalHeader
+ .short 0x206 // Characteristics.
+ // IMAGE_FILE_DEBUG_STRIPPED |
+ // IMAGE_FILE_EXECUTABLE_IMAGE |
+ // IMAGE_FILE_LINE_NUMS_STRIPPED
+optional_header:
+ .short 0x20b // PE32+ format
+ .byte 0x02 // MajorLinkerVersion
+ .byte 0x14 // MinorLinkerVersion
+ .long _end - efi_header_end // SizeOfCode
+ .long 0 // SizeOfInitializedData
+ .long 0 // SizeOfUninitializedData
+ .long __efistub_entry - _head // AddressOfEntryPoint
+ .long efi_header_end - _head // BaseOfCode
+
+extra_header_fields:
+ .quad 0 // ImageBase
+ .long 0x1000 // SectionAlignment
+ .long PECOFF_FILE_ALIGNMENT // FileAlignment
+ .short 0 // MajorOperatingSystemVersion
+ .short 0 // MinorOperatingSystemVersion
+ .short 0 // MajorImageVersion
+ .short 0 // MinorImageVersion
+ .short 0 // MajorSubsystemVersion
+ .short 0 // MinorSubsystemVersion
+ .long 0 // Win32VersionValue
+
+ .long _end - _head // SizeOfImage
+
+ // Everything before the kernel image is considered part of the header
+ .long efi_header_end - _head // SizeOfHeaders
+ .long 0 // CheckSum
+ .short 0xa // Subsystem (EFI application)
+ .short 0 // DllCharacteristics
+ .quad 0 // SizeOfStackReserve
+ .quad 0 // SizeOfStackCommit
+ .quad 0 // SizeOfHeapReserve
+ .quad 0 // SizeOfHeapCommit
+ .long 0 // LoaderFlags
+ .long (section_table - .) / 8 // NumberOfRvaAndSizes
+
+ .quad 0 // ExportTable
+ .quad 0 // ImportTable
+ .quad 0 // ResourceTable
+ .quad 0 // ExceptionTable
+ .quad 0 // CertificationTable
+ .quad 0 // BaseRelocationTable
+
+#ifdef CONFIG_DEBUG_EFI
+ .long efi_debug_table - _head // DebugTable
+ .long efi_debug_table_size
+#endif
+
+ // Section table
+section_table:
+
+ /*
+ * The EFI application loader requires a relocation section
+ * because EFI applications must be relocatable. This is a
+ * dummy section as far as we are concerned.
+ */
+ .ascii ".reloc"
+ .byte 0
+ .byte 0 // end of 0 padding of section name
+ .long 0
+ .long 0
+ .long 0 // SizeOfRawData
+ .long 0 // PointerToRawData
+ .long 0 // PointerToRelocations
+ .long 0 // PointerToLineNumbers
+ .short 0 // NumberOfRelocations
+ .short 0 // NumberOfLineNumbers
+ .long 0x42100040 // Characteristics (section flags)
+
+
+ .ascii ".text"
+ .byte 0
+ .byte 0
+ .byte 0 // end of 0 padding of section name
+ .long _end - efi_header_end // VirtualSize
+ .long efi_header_end - _head // VirtualAddress
+ .long _edata - efi_header_end // SizeOfRawData
+ .long efi_header_end - _head // PointerToRawData
+
+ .long 0 // PointerToRelocations
+ .long 0 // PointerToLineNumbers
+ .short 0 // NumberOfRelocations
+ .short 0 // NumberOfLineNumbers
+ .long 0xe0500020 // Characteristics
+
+#ifdef CONFIG_DEBUG_EFI
+ /*
+ * The debug table is referenced via its Relative Virtual Address (RVA),
+ * which is only defined for those parts of the image that are covered
+ * by a section declaration. Since this header is not covered by any
+ * section, the debug table must be emitted elsewhere. So stick it in
+ * the .init.rodata section instead.
+ *
+ * Note that the EFI debug entry itself may legally have a zero RVA,
+ * which means we can simply put it right after the section headers.
+ */
+ __INITRODATA
+
+ .align 2
+efi_debug_table:
+ // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
+ .long 0 // Characteristics
+ .long 0 // TimeDateStamp
+ .short 0 // MajorVersion
+ .short 0 // MinorVersion
+ .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
+ .long efi_debug_entry_size // SizeOfData
+ .long 0 // RVA
+ .long efi_debug_entry - _head // FileOffset
+
+ .set efi_debug_table_size, . - efi_debug_table
+ .previous
+
+efi_debug_entry:
+ // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
+ .ascii "NB10" // Signature
+ .long 0 // Unknown
+ .long 0 // Unknown2
+ .long 0 // Unknown3
+
+ .asciz VMLINUX_PATH
+
+ .set efi_debug_entry_size, . - efi_debug_entry
+#endif
+
+ /*
+ * EFI will load .text onwards at the 4k section alignment
+ * described in the PE/COFF header. To ensure that instruction
+ * sequences using an adrp and a :lo12: immediate will function
+ * correctly at this alignment, we must ensure that .text is
+ * placed at a 4k boundary in the Image to begin with.
+ */
+ .align 12
+efi_header_end:
+#endif
+ .endm
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index c6cc82ec190b..aca9b184035a 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -42,6 +42,8 @@
#include <asm/thread_info.h>
#include <asm/virt.h>
+#include "efi-header.S"
+
#define __PHYS_OFFSET (KERNEL_START - TEXT_OFFSET)
#if (TEXT_OFFSET & 0xfff) != 0
@@ -72,17 +74,7 @@ _head:
/*
* DO NOT MODIFY. Image header expected by Linux boot-loaders.
*/
-#ifdef CONFIG_EFI
- /*
- * This add instruction has no meaningful effect except that
- * its opcode forms the magic "MZ" signature required by UEFI.
- */
- add x13, x18, #0x16
- b stext
-#else
- b stext // branch to kernel start, magic
- .long 0 // reserved
-#endif
+ __jmp stext // Executable code
le64sym _kernel_offset_le // Image load offset from start of RAM, little-endian
le64sym _kernel_size_le // Effective size of kernel image, little-endian
le64sym _kernel_flags_le // Informative flags, little-endian
@@ -93,163 +85,8 @@ _head:
.byte 0x52
.byte 0x4d
.byte 0x64
-#ifdef CONFIG_EFI
- .long pe_header - _head // Offset to the PE header.
-#else
- .word 0 // reserved
-#endif
-
-#ifdef CONFIG_EFI
- .align 3
-pe_header:
- .ascii "PE"
- .short 0
-coff_header:
- .short 0xaa64 // AArch64
- .short 2 // nr_sections
- .long 0 // TimeDateStamp
- .long 0 // PointerToSymbolTable
- .long 1 // NumberOfSymbols
- .short section_table - optional_header // SizeOfOptionalHeader
- .short 0x206 // Characteristics.
- // IMAGE_FILE_DEBUG_STRIPPED |
- // IMAGE_FILE_EXECUTABLE_IMAGE |
- // IMAGE_FILE_LINE_NUMS_STRIPPED
-optional_header:
- .short 0x20b // PE32+ format
- .byte 0x02 // MajorLinkerVersion
- .byte 0x14 // MinorLinkerVersion
- .long _end - efi_header_end // SizeOfCode
- .long 0 // SizeOfInitializedData
- .long 0 // SizeOfUninitializedData
- .long __efistub_entry - _head // AddressOfEntryPoint
- .long efi_header_end - _head // BaseOfCode
-
-extra_header_fields:
- .quad 0 // ImageBase
- .long 0x1000 // SectionAlignment
- .long PECOFF_FILE_ALIGNMENT // FileAlignment
- .short 0 // MajorOperatingSystemVersion
- .short 0 // MinorOperatingSystemVersion
- .short 0 // MajorImageVersion
- .short 0 // MinorImageVersion
- .short 0 // MajorSubsystemVersion
- .short 0 // MinorSubsystemVersion
- .long 0 // Win32VersionValue
-
- .long _end - _head // SizeOfImage
-
- // Everything before the kernel image is considered part of the header
- .long efi_header_end - _head // SizeOfHeaders
- .long 0 // CheckSum
- .short 0xa // Subsystem (EFI application)
- .short 0 // DllCharacteristics
- .quad 0 // SizeOfStackReserve
- .quad 0 // SizeOfStackCommit
- .quad 0 // SizeOfHeapReserve
- .quad 0 // SizeOfHeapCommit
- .long 0 // LoaderFlags
- .long (section_table - .) / 8 // NumberOfRvaAndSizes
-
- .quad 0 // ExportTable
- .quad 0 // ImportTable
- .quad 0 // ResourceTable
- .quad 0 // ExceptionTable
- .quad 0 // CertificationTable
- .quad 0 // BaseRelocationTable
-
-#ifdef CONFIG_DEBUG_EFI
- .long efi_debug_table - _head // DebugTable
- .long efi_debug_table_size
-#endif
-
- // Section table
-section_table:
- /*
- * The EFI application loader requires a relocation section
- * because EFI applications must be relocatable. This is a
- * dummy section as far as we are concerned.
- */
- .ascii ".reloc"
- .byte 0
- .byte 0 // end of 0 padding of section name
- .long 0
- .long 0
- .long 0 // SizeOfRawData
- .long 0 // PointerToRawData
- .long 0 // PointerToRelocations
- .long 0 // PointerToLineNumbers
- .short 0 // NumberOfRelocations
- .short 0 // NumberOfLineNumbers
- .long 0x42100040 // Characteristics (section flags)
-
-
- .ascii ".text"
- .byte 0
- .byte 0
- .byte 0 // end of 0 padding of section name
- .long _end - efi_header_end // VirtualSize
- .long efi_header_end - _head // VirtualAddress
- .long _edata - efi_header_end // SizeOfRawData
- .long efi_header_end - _head // PointerToRawData
-
- .long 0 // PointerToRelocations (0 for executables)
- .long 0 // PointerToLineNumbers (0 for executables)
- .short 0 // NumberOfRelocations (0 for executables)
- .short 0 // NumberOfLineNumbers (0 for executables)
- .long 0xe0500020 // Characteristics (section flags)
-
-#ifdef CONFIG_DEBUG_EFI
- /*
- * The debug table is referenced via its Relative Virtual Address (RVA),
- * which is only defined for those parts of the image that are covered
- * by a section declaration. Since this header is not covered by any
- * section, the debug table must be emitted elsewhere. So stick it in
- * the .init.rodata section instead.
- *
- * Note that the EFI debug entry itself may legally have a zero RVA,
- * which means we can simply put it right after the section headers.
- */
- __INITRODATA
-
- .align 2
-efi_debug_table:
- // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
- .long 0 // Characteristics
- .long 0 // TimeDateStamp
- .short 0 // MajorVersion
- .short 0 // MinorVersion
- .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
- .long efi_debug_entry_size // SizeOfData
- .long 0 // RVA
- .long efi_debug_entry - _head // FileOffset
-
- .set efi_debug_table_size, . - efi_debug_table
- .previous
-
-efi_debug_entry:
- // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
- .ascii "NB10" // Signature
- .long 0 // Unknown
- .long 0 // Unknown2
- .long 0 // Unknown3
-
- .asciz VMLINUX_PATH
-
- .set efi_debug_entry_size, . - efi_debug_entry
-#endif
-
- /*
- * EFI will load .text onwards at the 4k section alignment
- * described in the PE/COFF header. To ensure that instruction
- * sequences using an adrp and a :lo12: immediate will function
- * correctly at this alignment, we must ensure that .text is
- * placed at a 4k boundary in the Image to begin with.
- */
- .align 12
-efi_header_end:
-#endif
+ __EFI_HEADER
__INIT
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 4/7] arm64: efi: ensure that the PE/COFF header pointer appears at offset 0x3c
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 16:24 ` Ard Biesheuvel
-1 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel
Use a .org directive to ensure that the PE/COFF header pointer appears
at offset 0x3c. Since the EFI header is now emitted using a macro, this
helps ensure that the invocation of the macro remains at the correct
offset.
At the same time, collapse two adjacent #ifdef CONFIG_EFI blocks into one,
and replace .word with .long (which are equivalent, but the former is
never used elsewhere)
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
| 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
--git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
index 8c8cd0a8192b..74a25c09a1b8 100644
--- a/arch/arm64/kernel/efi-header.S
+++ b/arch/arm64/kernel/efi-header.S
@@ -22,14 +22,16 @@
.endm
.macro __EFI_HEADER
-#ifdef CONFIG_EFI
- .long pe_header - _head // Offset to the PE header.
+#ifndef CONFIG_EFI
+ .long 0 // reserved
#else
- .word 0 // reserved
-#endif
+ /*
+ * PE/COFF requires the offset to the PE header
+ * to be stored at offset 0x3c into the file.
+ */
+ .org _head + 0x3c
+ .long pe_header - _head // Offset to the PE header.
-#ifdef CONFIG_EFI
- .align 3
pe_header:
.ascii "PE"
.short 0
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [kernel-hardening] [PATCH 4/7] arm64: efi: ensure that the PE/COFF header pointer appears at offset 0x3c
@ 2017-02-06 16:24 ` Ard Biesheuvel
0 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel, will.deacon, catalin.marinas, mark.rutland
Cc: labbott, kernel-hardening, leif.lindholm, pjones, Ard Biesheuvel
Use a .org directive to ensure that the PE/COFF header pointer appears
at offset 0x3c. Since the EFI header is now emitted using a macro, this
helps ensure that the invocation of the macro remains at the correct
offset.
At the same time, collapse two adjacent #ifdef CONFIG_EFI blocks into one,
and replace .word with .long (which are equivalent, but the former is
never used elsewhere)
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
| 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
--git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
index 8c8cd0a8192b..74a25c09a1b8 100644
--- a/arch/arm64/kernel/efi-header.S
+++ b/arch/arm64/kernel/efi-header.S
@@ -22,14 +22,16 @@
.endm
.macro __EFI_HEADER
-#ifdef CONFIG_EFI
- .long pe_header - _head // Offset to the PE header.
+#ifndef CONFIG_EFI
+ .long 0 // reserved
#else
- .word 0 // reserved
-#endif
+ /*
+ * PE/COFF requires the offset to the PE header
+ * to be stored at offset 0x3c into the file.
+ */
+ .org _head + 0x3c
+ .long pe_header - _head // Offset to the PE header.
-#ifdef CONFIG_EFI
- .align 3
pe_header:
.ascii "PE"
.short 0
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 5/7] arm64: efi: remove pointless dummy .reloc section
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 16:24 ` Ard Biesheuvel
-1 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel
The kernel's EFI PE/COFF header contains a dummy .reloc section, and
an explanatory comment that claims that this is required for the EFI
application loader to accept the Image as a relocatable image (i.e.,
one that can be loaded at any offset and fixed up in place)
This was inherited from the x86 implementation, which has elaborate host
tooling to mangle the PE/COFF header post-link time, and which populates
the .reloc section with a single dummy base relocation. On ARM, no such
tooling exists, and the .reloc section remains empty, and is never even
exposed via the BaseRelocationTable directory entry, which is where the
PE/COFF loader looks for it.
The PE/COFF spec is unclear about relocatable images that do not require
any fixups, but the EDK2 implementation, which is the de facto reference
for PE/COFF in the UEFI space, clearly does not care, and explicitly
mentions (in a comment) that relocatable images with no base relocations
are perfectly fine, as long as they don't have the RELOCS_STRIPPED
attribute set (which is not the case for our PE/COFF image)
So simply remove the .reloc section altogether.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
| 22 +-------------------
1 file changed, 1 insertion(+), 21 deletions(-)
--git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
index 74a25c09a1b8..35b11654ecc5 100644
--- a/arch/arm64/kernel/efi-header.S
+++ b/arch/arm64/kernel/efi-header.S
@@ -37,7 +37,7 @@ pe_header:
.short 0
coff_header:
.short 0xaa64 // AArch64
- .short 2 // nr_sections
+ .short 1 // nr_sections
.long 0 // TimeDateStamp
.long 0 // PointerToSymbolTable
.long 1 // NumberOfSymbols
@@ -96,26 +96,6 @@ extra_header_fields:
// Section table
section_table:
-
- /*
- * The EFI application loader requires a relocation section
- * because EFI applications must be relocatable. This is a
- * dummy section as far as we are concerned.
- */
- .ascii ".reloc"
- .byte 0
- .byte 0 // end of 0 padding of section name
- .long 0
- .long 0
- .long 0 // SizeOfRawData
- .long 0 // PointerToRawData
- .long 0 // PointerToRelocations
- .long 0 // PointerToLineNumbers
- .short 0 // NumberOfRelocations
- .short 0 // NumberOfLineNumbers
- .long 0x42100040 // Characteristics (section flags)
-
-
.ascii ".text"
.byte 0
.byte 0
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [kernel-hardening] [PATCH 5/7] arm64: efi: remove pointless dummy .reloc section
@ 2017-02-06 16:24 ` Ard Biesheuvel
0 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel, will.deacon, catalin.marinas, mark.rutland
Cc: labbott, kernel-hardening, leif.lindholm, pjones, Ard Biesheuvel
The kernel's EFI PE/COFF header contains a dummy .reloc section, and
an explanatory comment that claims that this is required for the EFI
application loader to accept the Image as a relocatable image (i.e.,
one that can be loaded at any offset and fixed up in place)
This was inherited from the x86 implementation, which has elaborate host
tooling to mangle the PE/COFF header post-link time, and which populates
the .reloc section with a single dummy base relocation. On ARM, no such
tooling exists, and the .reloc section remains empty, and is never even
exposed via the BaseRelocationTable directory entry, which is where the
PE/COFF loader looks for it.
The PE/COFF spec is unclear about relocatable images that do not require
any fixups, but the EDK2 implementation, which is the de facto reference
for PE/COFF in the UEFI space, clearly does not care, and explicitly
mentions (in a comment) that relocatable images with no base relocations
are perfectly fine, as long as they don't have the RELOCS_STRIPPED
attribute set (which is not the case for our PE/COFF image)
So simply remove the .reloc section altogether.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
| 22 +-------------------
1 file changed, 1 insertion(+), 21 deletions(-)
--git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
index 74a25c09a1b8..35b11654ecc5 100644
--- a/arch/arm64/kernel/efi-header.S
+++ b/arch/arm64/kernel/efi-header.S
@@ -37,7 +37,7 @@ pe_header:
.short 0
coff_header:
.short 0xaa64 // AArch64
- .short 2 // nr_sections
+ .short 1 // nr_sections
.long 0 // TimeDateStamp
.long 0 // PointerToSymbolTable
.long 1 // NumberOfSymbols
@@ -96,26 +96,6 @@ extra_header_fields:
// Section table
section_table:
-
- /*
- * The EFI application loader requires a relocation section
- * because EFI applications must be relocatable. This is a
- * dummy section as far as we are concerned.
- */
- .ascii ".reloc"
- .byte 0
- .byte 0 // end of 0 padding of section name
- .long 0
- .long 0
- .long 0 // SizeOfRawData
- .long 0 // PointerToRawData
- .long 0 // PointerToRelocations
- .long 0 // PointerToLineNumbers
- .short 0 // NumberOfRelocations
- .short 0 // NumberOfLineNumbers
- .long 0x42100040 // Characteristics (section flags)
-
-
.ascii ".text"
.byte 0
.byte 0
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 6/7] arm64: efi: replace open coded constants with symbolic ones
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 16:24 ` Ard Biesheuvel
-1 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel
Replace open coded constants with symbolic ones throughout the
Image and the EFI headers. Note that in two cases, this removes
a value that the PE/COFF spec does not allow:
- NumberOfSymbols in the PE header should be 0
- PE/COFF executable sections (as opposed to sections in object files)
should not use the section alignment flags
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
| 37 ++++++++++----------
arch/arm64/kernel/head.S | 5 +--
2 files changed, 20 insertions(+), 22 deletions(-)
--git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
index 35b11654ecc5..c87c23336c86 100644
--- a/arch/arm64/kernel/efi-header.S
+++ b/arch/arm64/kernel/efi-header.S
@@ -7,6 +7,8 @@
* published by the Free Software Foundation.
*/
+#include <linux/pe.h>
+
.macro __jmp, target
#ifdef CONFIG_EFI
/*
@@ -33,21 +35,20 @@
.long pe_header - _head // Offset to the PE header.
pe_header:
- .ascii "PE"
- .short 0
+ .long PE_MAGIC
coff_header:
- .short 0xaa64 // AArch64
- .short 1 // nr_sections
+ .short IMAGE_FILE_MACHINE_ARM64 // Machine
+ .short 1 // NumberOfSections
.long 0 // TimeDateStamp
.long 0 // PointerToSymbolTable
- .long 1 // NumberOfSymbols
+ .long 0 // NumberOfSymbols
.short section_table - optional_header // SizeOfOptionalHeader
- .short 0x206 // Characteristics.
- // IMAGE_FILE_DEBUG_STRIPPED |
- // IMAGE_FILE_EXECUTABLE_IMAGE |
- // IMAGE_FILE_LINE_NUMS_STRIPPED
+ .short IMAGE_FILE_DEBUG_STRIPPED | \
+ IMAGE_FILE_EXECUTABLE_IMAGE | \
+ IMAGE_FILE_LINE_NUMS_STRIPPED // Characteristics
+
optional_header:
- .short 0x20b // PE32+ format
+ .short PE_OPT_MAGIC_PE32PLUS // PE32+ format
.byte 0x02 // MajorLinkerVersion
.byte 0x14 // MinorLinkerVersion
.long _end - efi_header_end // SizeOfCode
@@ -58,7 +59,7 @@ optional_header:
extra_header_fields:
.quad 0 // ImageBase
- .long 0x1000 // SectionAlignment
+ .long SZ_4K // SectionAlignment
.long PECOFF_FILE_ALIGNMENT // FileAlignment
.short 0 // MajorOperatingSystemVersion
.short 0 // MinorOperatingSystemVersion
@@ -73,7 +74,7 @@ extra_header_fields:
// Everything before the kernel image is considered part of the header
.long efi_header_end - _head // SizeOfHeaders
.long 0 // CheckSum
- .short 0xa // Subsystem (EFI application)
+ .short IMAGE_SUBSYSTEM_EFI_APPLICATION // Subsystem
.short 0 // DllCharacteristics
.quad 0 // SizeOfStackReserve
.quad 0 // SizeOfStackCommit
@@ -96,10 +97,7 @@ extra_header_fields:
// Section table
section_table:
- .ascii ".text"
- .byte 0
- .byte 0
- .byte 0 // end of 0 padding of section name
+ .ascii ".text\0\0\0"
.long _end - efi_header_end // VirtualSize
.long efi_header_end - _head // VirtualAddress
.long _edata - efi_header_end // SizeOfRawData
@@ -109,7 +107,10 @@ section_table:
.long 0 // PointerToLineNumbers
.short 0 // NumberOfRelocations
.short 0 // NumberOfLineNumbers
- .long 0xe0500020 // Characteristics
+ .long IMAGE_SCN_CNT_CODE | \
+ IMAGE_SCN_MEM_EXECUTE | \
+ IMAGE_SCN_MEM_READ | \
+ IMAGE_SCN_MEM_WRITE // Characteristics
#ifdef CONFIG_DEBUG_EFI
/*
@@ -131,7 +132,7 @@ efi_debug_table:
.long 0 // TimeDateStamp
.short 0 // MajorVersion
.short 0 // MinorVersion
- .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
+ .long IMAGE_DEBUG_TYPE_CODEVIEW // Type
.long efi_debug_entry_size // SizeOfData
.long 0 // RVA
.long efi_debug_entry - _head // FileOffset
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index aca9b184035a..055735ba3600 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -81,10 +81,7 @@ _head:
.quad 0 // reserved
.quad 0 // reserved
.quad 0 // reserved
- .byte 0x41 // Magic number, "ARM\x64"
- .byte 0x52
- .byte 0x4d
- .byte 0x64
+ .ascii "ARM\x64" // Magic number
__EFI_HEADER
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [kernel-hardening] [PATCH 6/7] arm64: efi: replace open coded constants with symbolic ones
@ 2017-02-06 16:24 ` Ard Biesheuvel
0 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel, will.deacon, catalin.marinas, mark.rutland
Cc: labbott, kernel-hardening, leif.lindholm, pjones, Ard Biesheuvel
Replace open coded constants with symbolic ones throughout the
Image and the EFI headers. Note that in two cases, this removes
a value that the PE/COFF spec does not allow:
- NumberOfSymbols in the PE header should be 0
- PE/COFF executable sections (as opposed to sections in object files)
should not use the section alignment flags
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
| 37 ++++++++++----------
arch/arm64/kernel/head.S | 5 +--
2 files changed, 20 insertions(+), 22 deletions(-)
--git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
index 35b11654ecc5..c87c23336c86 100644
--- a/arch/arm64/kernel/efi-header.S
+++ b/arch/arm64/kernel/efi-header.S
@@ -7,6 +7,8 @@
* published by the Free Software Foundation.
*/
+#include <linux/pe.h>
+
.macro __jmp, target
#ifdef CONFIG_EFI
/*
@@ -33,21 +35,20 @@
.long pe_header - _head // Offset to the PE header.
pe_header:
- .ascii "PE"
- .short 0
+ .long PE_MAGIC
coff_header:
- .short 0xaa64 // AArch64
- .short 1 // nr_sections
+ .short IMAGE_FILE_MACHINE_ARM64 // Machine
+ .short 1 // NumberOfSections
.long 0 // TimeDateStamp
.long 0 // PointerToSymbolTable
- .long 1 // NumberOfSymbols
+ .long 0 // NumberOfSymbols
.short section_table - optional_header // SizeOfOptionalHeader
- .short 0x206 // Characteristics.
- // IMAGE_FILE_DEBUG_STRIPPED |
- // IMAGE_FILE_EXECUTABLE_IMAGE |
- // IMAGE_FILE_LINE_NUMS_STRIPPED
+ .short IMAGE_FILE_DEBUG_STRIPPED | \
+ IMAGE_FILE_EXECUTABLE_IMAGE | \
+ IMAGE_FILE_LINE_NUMS_STRIPPED // Characteristics
+
optional_header:
- .short 0x20b // PE32+ format
+ .short PE_OPT_MAGIC_PE32PLUS // PE32+ format
.byte 0x02 // MajorLinkerVersion
.byte 0x14 // MinorLinkerVersion
.long _end - efi_header_end // SizeOfCode
@@ -58,7 +59,7 @@ optional_header:
extra_header_fields:
.quad 0 // ImageBase
- .long 0x1000 // SectionAlignment
+ .long SZ_4K // SectionAlignment
.long PECOFF_FILE_ALIGNMENT // FileAlignment
.short 0 // MajorOperatingSystemVersion
.short 0 // MinorOperatingSystemVersion
@@ -73,7 +74,7 @@ extra_header_fields:
// Everything before the kernel image is considered part of the header
.long efi_header_end - _head // SizeOfHeaders
.long 0 // CheckSum
- .short 0xa // Subsystem (EFI application)
+ .short IMAGE_SUBSYSTEM_EFI_APPLICATION // Subsystem
.short 0 // DllCharacteristics
.quad 0 // SizeOfStackReserve
.quad 0 // SizeOfStackCommit
@@ -96,10 +97,7 @@ extra_header_fields:
// Section table
section_table:
- .ascii ".text"
- .byte 0
- .byte 0
- .byte 0 // end of 0 padding of section name
+ .ascii ".text\0\0\0"
.long _end - efi_header_end // VirtualSize
.long efi_header_end - _head // VirtualAddress
.long _edata - efi_header_end // SizeOfRawData
@@ -109,7 +107,10 @@ section_table:
.long 0 // PointerToLineNumbers
.short 0 // NumberOfRelocations
.short 0 // NumberOfLineNumbers
- .long 0xe0500020 // Characteristics
+ .long IMAGE_SCN_CNT_CODE | \
+ IMAGE_SCN_MEM_EXECUTE | \
+ IMAGE_SCN_MEM_READ | \
+ IMAGE_SCN_MEM_WRITE // Characteristics
#ifdef CONFIG_DEBUG_EFI
/*
@@ -131,7 +132,7 @@ efi_debug_table:
.long 0 // TimeDateStamp
.short 0 // MajorVersion
.short 0 // MinorVersion
- .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
+ .long IMAGE_DEBUG_TYPE_CODEVIEW // Type
.long efi_debug_entry_size // SizeOfData
.long 0 // RVA
.long efi_debug_entry - _head // FileOffset
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index aca9b184035a..055735ba3600 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -81,10 +81,7 @@ _head:
.quad 0 // reserved
.quad 0 // reserved
.quad 0 // reserved
- .byte 0x41 // Magic number, "ARM\x64"
- .byte 0x52
- .byte 0x4d
- .byte 0x64
+ .ascii "ARM\x64" // Magic number
__EFI_HEADER
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 7/7] arm64: efi: split Image code and data into separate PE/COFF sections
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 16:24 ` Ard Biesheuvel
-1 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel
To prevent unintended modifications to the kernel text (malicious or
otherwise) while running the EFI stub, describe the kernel image as
two separate sections: a .text section with read-execute permissions,
covering .text, .rodata and .init.text, and a .data section with
read-write permissions, covering .init.data, .data and .bss.
This relies on the firmware to actually take the section permission
flags into account, but this is something that is currently being
implemented in EDK2, which means we will likely start seeing it in
the wild between one and two years from now.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
| 25 +++++++++++++++-----
arch/arm64/kernel/vmlinux.lds.S | 5 ++++
2 files changed, 24 insertions(+), 6 deletions(-)
--git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
index c87c23336c86..fc93ab48f69a 100644
--- a/arch/arm64/kernel/efi-header.S
+++ b/arch/arm64/kernel/efi-header.S
@@ -38,7 +38,7 @@ pe_header:
.long PE_MAGIC
coff_header:
.short IMAGE_FILE_MACHINE_ARM64 // Machine
- .short 1 // NumberOfSections
+ .short 2 // NumberOfSections
.long 0 // TimeDateStamp
.long 0 // PointerToSymbolTable
.long 0 // NumberOfSymbols
@@ -51,8 +51,8 @@ optional_header:
.short PE_OPT_MAGIC_PE32PLUS // PE32+ format
.byte 0x02 // MajorLinkerVersion
.byte 0x14 // MinorLinkerVersion
- .long _end - efi_header_end // SizeOfCode
- .long 0 // SizeOfInitializedData
+ .long __pecoff_data_start - efi_header_end // SizeOfCode
+ .long __pecoff_data_size // SizeOfInitializedData
.long 0 // SizeOfUninitializedData
.long __efistub_entry - _head // AddressOfEntryPoint
.long efi_header_end - _head // BaseOfCode
@@ -98,9 +98,9 @@ extra_header_fields:
// Section table
section_table:
.ascii ".text\0\0\0"
- .long _end - efi_header_end // VirtualSize
+ .long __pecoff_data_start - efi_header_end // VirtualSize
.long efi_header_end - _head // VirtualAddress
- .long _edata - efi_header_end // SizeOfRawData
+ .long __pecoff_data_start - efi_header_end // SizeOfRawData
.long efi_header_end - _head // PointerToRawData
.long 0 // PointerToRelocations
@@ -108,7 +108,20 @@ section_table:
.short 0 // NumberOfRelocations
.short 0 // NumberOfLineNumbers
.long IMAGE_SCN_CNT_CODE | \
- IMAGE_SCN_MEM_EXECUTE | \
+ IMAGE_SCN_MEM_READ | \
+ IMAGE_SCN_MEM_EXECUTE // Characteristics
+
+ .ascii ".data\0\0\0"
+ .long __pecoff_data_size // VirtualSize
+ .long __pecoff_data_start - _head // VirtualAddress
+ .long __pecoff_data_rawsize // SizeOfRawData
+ .long __pecoff_data_start - _head // PointerToRawData
+
+ .long 0 // PointerToRelocations
+ .long 0 // PointerToLineNumbers
+ .short 0 // NumberOfRelocations
+ .short 0 // NumberOfLineNumbers
+ .long IMAGE_SCN_CNT_INITIALIZED_DATA | \
IMAGE_SCN_MEM_READ | \
IMAGE_SCN_MEM_WRITE // Characteristics
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index b8deffa9e1bf..a93cc2b6f50b 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -149,6 +149,9 @@ SECTIONS
ARM_EXIT_KEEP(EXIT_TEXT)
}
+ . = ALIGN(SZ_4K);
+ __pecoff_data_start = .;
+
.init.data : {
INIT_DATA
INIT_SETUP(16)
@@ -206,6 +209,7 @@ SECTIONS
}
PECOFF_EDATA_PADDING
+ __pecoff_data_rawsize = ABSOLUTE(. - __pecoff_data_start);
_edata = .;
BSS_SECTION(0, 0, 0)
@@ -221,6 +225,7 @@ SECTIONS
. += RESERVED_TTBR0_SIZE;
#endif
+ __pecoff_data_size = ABSOLUTE(. - __pecoff_data_start);
_end = .;
STABS_DEBUG
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [kernel-hardening] [PATCH 7/7] arm64: efi: split Image code and data into separate PE/COFF sections
@ 2017-02-06 16:24 ` Ard Biesheuvel
0 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:24 UTC (permalink / raw)
To: linux-arm-kernel, will.deacon, catalin.marinas, mark.rutland
Cc: labbott, kernel-hardening, leif.lindholm, pjones, Ard Biesheuvel
To prevent unintended modifications to the kernel text (malicious or
otherwise) while running the EFI stub, describe the kernel image as
two separate sections: a .text section with read-execute permissions,
covering .text, .rodata and .init.text, and a .data section with
read-write permissions, covering .init.data, .data and .bss.
This relies on the firmware to actually take the section permission
flags into account, but this is something that is currently being
implemented in EDK2, which means we will likely start seeing it in
the wild between one and two years from now.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
| 25 +++++++++++++++-----
arch/arm64/kernel/vmlinux.lds.S | 5 ++++
2 files changed, 24 insertions(+), 6 deletions(-)
--git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
index c87c23336c86..fc93ab48f69a 100644
--- a/arch/arm64/kernel/efi-header.S
+++ b/arch/arm64/kernel/efi-header.S
@@ -38,7 +38,7 @@ pe_header:
.long PE_MAGIC
coff_header:
.short IMAGE_FILE_MACHINE_ARM64 // Machine
- .short 1 // NumberOfSections
+ .short 2 // NumberOfSections
.long 0 // TimeDateStamp
.long 0 // PointerToSymbolTable
.long 0 // NumberOfSymbols
@@ -51,8 +51,8 @@ optional_header:
.short PE_OPT_MAGIC_PE32PLUS // PE32+ format
.byte 0x02 // MajorLinkerVersion
.byte 0x14 // MinorLinkerVersion
- .long _end - efi_header_end // SizeOfCode
- .long 0 // SizeOfInitializedData
+ .long __pecoff_data_start - efi_header_end // SizeOfCode
+ .long __pecoff_data_size // SizeOfInitializedData
.long 0 // SizeOfUninitializedData
.long __efistub_entry - _head // AddressOfEntryPoint
.long efi_header_end - _head // BaseOfCode
@@ -98,9 +98,9 @@ extra_header_fields:
// Section table
section_table:
.ascii ".text\0\0\0"
- .long _end - efi_header_end // VirtualSize
+ .long __pecoff_data_start - efi_header_end // VirtualSize
.long efi_header_end - _head // VirtualAddress
- .long _edata - efi_header_end // SizeOfRawData
+ .long __pecoff_data_start - efi_header_end // SizeOfRawData
.long efi_header_end - _head // PointerToRawData
.long 0 // PointerToRelocations
@@ -108,7 +108,20 @@ section_table:
.short 0 // NumberOfRelocations
.short 0 // NumberOfLineNumbers
.long IMAGE_SCN_CNT_CODE | \
- IMAGE_SCN_MEM_EXECUTE | \
+ IMAGE_SCN_MEM_READ | \
+ IMAGE_SCN_MEM_EXECUTE // Characteristics
+
+ .ascii ".data\0\0\0"
+ .long __pecoff_data_size // VirtualSize
+ .long __pecoff_data_start - _head // VirtualAddress
+ .long __pecoff_data_rawsize // SizeOfRawData
+ .long __pecoff_data_start - _head // PointerToRawData
+
+ .long 0 // PointerToRelocations
+ .long 0 // PointerToLineNumbers
+ .short 0 // NumberOfRelocations
+ .short 0 // NumberOfLineNumbers
+ .long IMAGE_SCN_CNT_INITIALIZED_DATA | \
IMAGE_SCN_MEM_READ | \
IMAGE_SCN_MEM_WRITE // Characteristics
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index b8deffa9e1bf..a93cc2b6f50b 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -149,6 +149,9 @@ SECTIONS
ARM_EXIT_KEEP(EXIT_TEXT)
}
+ . = ALIGN(SZ_4K);
+ __pecoff_data_start = .;
+
.init.data : {
INIT_DATA
INIT_SETUP(16)
@@ -206,6 +209,7 @@ SECTIONS
}
PECOFF_EDATA_PADDING
+ __pecoff_data_rawsize = ABSOLUTE(. - __pecoff_data_start);
_edata = .;
BSS_SECTION(0, 0, 0)
@@ -221,6 +225,7 @@ SECTIONS
. += RESERVED_TTBR0_SIZE;
#endif
+ __pecoff_data_size = ABSOLUTE(. - __pecoff_data_start);
_end = .;
STABS_DEBUG
--
2.7.4
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 1/7] include: pe.h: allow for use in assembly
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 16:33 ` Mark Rutland
-1 siblings, 0 replies; 32+ messages in thread
From: Mark Rutland @ 2017-02-06 16:33 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 06, 2017 at 04:24:29PM +0000, Ard Biesheuvel wrote:
> From: Mark Rutland <mark.rutland@arm.com>
>
> Some of the definitions in include/linux/pe.h would be useful for the
> EFI stub headers, where values are currently open-coded. Unfortunately
> they cannot be used as some structures are also defined in pe.h without
> !__ASSEMBLY__ guards.
>
> This patch moves the structure definitions into an #ifdef __ASSEMBLY__
> block, so that the common value definitions can be used from assembly.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> ---
> include/linux/pe.h | 174 ++++++++++----------
> 1 file changed, 89 insertions(+), 85 deletions(-)
Do remember that you need to add your own Signed-off-by for patches you
pick up! :)
Mark.
>
> diff --git a/include/linux/pe.h b/include/linux/pe.h
> index e170b95e763b..a8a594117df3 100644
> --- a/include/linux/pe.h
> +++ b/include/linux/pe.h
> @@ -23,34 +23,6 @@
>
> #define MZ_MAGIC 0x5a4d /* "MZ" */
>
> -struct mz_hdr {
> - uint16_t magic; /* MZ_MAGIC */
> - uint16_t lbsize; /* size of last used block */
> - uint16_t blocks; /* pages in file, 0x3 */
> - uint16_t relocs; /* relocations */
> - uint16_t hdrsize; /* header size in "paragraphs" */
> - uint16_t min_extra_pps; /* .bss */
> - uint16_t max_extra_pps; /* runtime limit for the arena size */
> - uint16_t ss; /* relative stack segment */
> - uint16_t sp; /* initial %sp register */
> - uint16_t checksum; /* word checksum */
> - uint16_t ip; /* initial %ip register */
> - uint16_t cs; /* initial %cs relative to load segment */
> - uint16_t reloc_table_offset; /* offset of the first relocation */
> - uint16_t overlay_num; /* overlay number. set to 0. */
> - uint16_t reserved0[4]; /* reserved */
> - uint16_t oem_id; /* oem identifier */
> - uint16_t oem_info; /* oem specific */
> - uint16_t reserved1[10]; /* reserved */
> - uint32_t peaddr; /* address of pe header */
> - char message[64]; /* message to print */
> -};
> -
> -struct mz_reloc {
> - uint16_t offset;
> - uint16_t segment;
> -};
> -
> #define PE_MAGIC 0x00004550 /* "PE\0\0" */
> #define PE_OPT_MAGIC_PE32 0x010b
> #define PE_OPT_MAGIC_PE32_ROM 0x0107
> @@ -98,17 +70,6 @@ struct mz_reloc {
> #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
> #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
>
> -struct pe_hdr {
> - uint32_t magic; /* PE magic */
> - uint16_t machine; /* machine type */
> - uint16_t sections; /* number of sections */
> - uint32_t timestamp; /* time_t */
> - uint32_t symbol_table; /* symbol table offset */
> - uint32_t symbols; /* number of symbols */
> - uint16_t opt_hdr_size; /* size of optional header */
> - uint16_t flags; /* flags */
> -};
> -
> #define IMAGE_FILE_OPT_ROM_MAGIC 0x107
> #define IMAGE_FILE_OPT_PE32_MAGIC 0x10b
> #define IMAGE_FILE_OPT_PE32_PLUS_MAGIC 0x20b
> @@ -134,6 +95,93 @@ struct pe_hdr {
> #define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000
> #define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
>
> +/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
> +#define IMAGE_SCN_RESERVED_0 0x00000001
> +#define IMAGE_SCN_RESERVED_1 0x00000002
> +#define IMAGE_SCN_RESERVED_2 0x00000004
> +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
> +#define IMAGE_SCN_RESERVED_3 0x00000010
> +#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
> +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
> +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
> +#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
> +#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
> +#define IMAGE_SCN_RESERVED_4 0x00000400
> +#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
> +#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
> +#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
> +#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
> +#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
> +/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
> +#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
> +#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
> +#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
> +#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
> +/* and here they just stuck a 1-byte integer in the middle of a bitfield */
> +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
> +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
> +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
> +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
> +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
> +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
> +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
> +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
> +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
> +#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
> +#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
> +#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
> +#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
> +#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
> +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
> +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
> +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
> +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
> +#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
> +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
> +#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
> +#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
> +
> +#ifndef __ASSEMBLY__
> +
> +struct mz_hdr {
> + uint16_t magic; /* MZ_MAGIC */
> + uint16_t lbsize; /* size of last used block */
> + uint16_t blocks; /* pages in file, 0x3 */
> + uint16_t relocs; /* relocations */
> + uint16_t hdrsize; /* header size in "paragraphs" */
> + uint16_t min_extra_pps; /* .bss */
> + uint16_t max_extra_pps; /* runtime limit for the arena size */
> + uint16_t ss; /* relative stack segment */
> + uint16_t sp; /* initial %sp register */
> + uint16_t checksum; /* word checksum */
> + uint16_t ip; /* initial %ip register */
> + uint16_t cs; /* initial %cs relative to load segment */
> + uint16_t reloc_table_offset; /* offset of the first relocation */
> + uint16_t overlay_num; /* overlay number. set to 0. */
> + uint16_t reserved0[4]; /* reserved */
> + uint16_t oem_id; /* oem identifier */
> + uint16_t oem_info; /* oem specific */
> + uint16_t reserved1[10]; /* reserved */
> + uint32_t peaddr; /* address of pe header */
> + char message[64]; /* message to print */
> +};
> +
> +struct mz_reloc {
> + uint16_t offset;
> + uint16_t segment;
> +};
> +
> +struct pe_hdr {
> + uint32_t magic; /* PE magic */
> + uint16_t machine; /* machine type */
> + uint16_t sections; /* number of sections */
> + uint32_t timestamp; /* time_t */
> + uint32_t symbol_table; /* symbol table offset */
> + uint32_t symbols; /* number of symbols */
> + uint16_t opt_hdr_size; /* size of optional header */
> + uint16_t flags; /* flags */
> +};
> +
> /* the fact that pe32 isn't padded where pe32+ is 64-bit means union won't
> * work right. vomit. */
> struct pe32_opt_hdr {
> @@ -243,52 +291,6 @@ struct section_header {
> uint32_t flags;
> };
>
> -/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
> -#define IMAGE_SCN_RESERVED_0 0x00000001
> -#define IMAGE_SCN_RESERVED_1 0x00000002
> -#define IMAGE_SCN_RESERVED_2 0x00000004
> -#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
> -#define IMAGE_SCN_RESERVED_3 0x00000010
> -#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
> -#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
> -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
> -#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
> -#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
> -#define IMAGE_SCN_RESERVED_4 0x00000400
> -#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
> -#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
> -#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
> -#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
> -#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
> -/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
> -#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
> -#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
> -#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
> -#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
> -/* and here they just stuck a 1-byte integer in the middle of a bitfield */
> -#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
> -#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
> -#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
> -#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
> -#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
> -#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
> -#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
> -#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
> -#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
> -#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
> -#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
> -#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
> -#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
> -#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
> -#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
> -#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
> -#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
> -#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
> -#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
> -#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
> -#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
> -#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
> -
> enum x64_coff_reloc_type {
> IMAGE_REL_AMD64_ABSOLUTE = 0,
> IMAGE_REL_AMD64_ADDR64,
> @@ -445,4 +447,6 @@ struct win_certificate {
> uint16_t cert_type;
> };
>
> +#endif /* !__ASSEMBLY__ */
> +
> #endif /* __LINUX_PE_H */
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [kernel-hardening] Re: [PATCH 1/7] include: pe.h: allow for use in assembly
@ 2017-02-06 16:33 ` Mark Rutland
0 siblings, 0 replies; 32+ messages in thread
From: Mark Rutland @ 2017-02-06 16:33 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-arm-kernel, will.deacon, catalin.marinas, labbott,
kernel-hardening, leif.lindholm, pjones
On Mon, Feb 06, 2017 at 04:24:29PM +0000, Ard Biesheuvel wrote:
> From: Mark Rutland <mark.rutland@arm.com>
>
> Some of the definitions in include/linux/pe.h would be useful for the
> EFI stub headers, where values are currently open-coded. Unfortunately
> they cannot be used as some structures are also defined in pe.h without
> !__ASSEMBLY__ guards.
>
> This patch moves the structure definitions into an #ifdef __ASSEMBLY__
> block, so that the common value definitions can be used from assembly.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> ---
> include/linux/pe.h | 174 ++++++++++----------
> 1 file changed, 89 insertions(+), 85 deletions(-)
Do remember that you need to add your own Signed-off-by for patches you
pick up! :)
Mark.
>
> diff --git a/include/linux/pe.h b/include/linux/pe.h
> index e170b95e763b..a8a594117df3 100644
> --- a/include/linux/pe.h
> +++ b/include/linux/pe.h
> @@ -23,34 +23,6 @@
>
> #define MZ_MAGIC 0x5a4d /* "MZ" */
>
> -struct mz_hdr {
> - uint16_t magic; /* MZ_MAGIC */
> - uint16_t lbsize; /* size of last used block */
> - uint16_t blocks; /* pages in file, 0x3 */
> - uint16_t relocs; /* relocations */
> - uint16_t hdrsize; /* header size in "paragraphs" */
> - uint16_t min_extra_pps; /* .bss */
> - uint16_t max_extra_pps; /* runtime limit for the arena size */
> - uint16_t ss; /* relative stack segment */
> - uint16_t sp; /* initial %sp register */
> - uint16_t checksum; /* word checksum */
> - uint16_t ip; /* initial %ip register */
> - uint16_t cs; /* initial %cs relative to load segment */
> - uint16_t reloc_table_offset; /* offset of the first relocation */
> - uint16_t overlay_num; /* overlay number. set to 0. */
> - uint16_t reserved0[4]; /* reserved */
> - uint16_t oem_id; /* oem identifier */
> - uint16_t oem_info; /* oem specific */
> - uint16_t reserved1[10]; /* reserved */
> - uint32_t peaddr; /* address of pe header */
> - char message[64]; /* message to print */
> -};
> -
> -struct mz_reloc {
> - uint16_t offset;
> - uint16_t segment;
> -};
> -
> #define PE_MAGIC 0x00004550 /* "PE\0\0" */
> #define PE_OPT_MAGIC_PE32 0x010b
> #define PE_OPT_MAGIC_PE32_ROM 0x0107
> @@ -98,17 +70,6 @@ struct mz_reloc {
> #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
> #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
>
> -struct pe_hdr {
> - uint32_t magic; /* PE magic */
> - uint16_t machine; /* machine type */
> - uint16_t sections; /* number of sections */
> - uint32_t timestamp; /* time_t */
> - uint32_t symbol_table; /* symbol table offset */
> - uint32_t symbols; /* number of symbols */
> - uint16_t opt_hdr_size; /* size of optional header */
> - uint16_t flags; /* flags */
> -};
> -
> #define IMAGE_FILE_OPT_ROM_MAGIC 0x107
> #define IMAGE_FILE_OPT_PE32_MAGIC 0x10b
> #define IMAGE_FILE_OPT_PE32_PLUS_MAGIC 0x20b
> @@ -134,6 +95,93 @@ struct pe_hdr {
> #define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000
> #define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
>
> +/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
> +#define IMAGE_SCN_RESERVED_0 0x00000001
> +#define IMAGE_SCN_RESERVED_1 0x00000002
> +#define IMAGE_SCN_RESERVED_2 0x00000004
> +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
> +#define IMAGE_SCN_RESERVED_3 0x00000010
> +#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
> +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
> +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
> +#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
> +#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
> +#define IMAGE_SCN_RESERVED_4 0x00000400
> +#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
> +#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
> +#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
> +#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
> +#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
> +/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
> +#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
> +#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
> +#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
> +#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
> +/* and here they just stuck a 1-byte integer in the middle of a bitfield */
> +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
> +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
> +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
> +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
> +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
> +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
> +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
> +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
> +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
> +#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
> +#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
> +#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
> +#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
> +#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
> +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
> +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
> +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
> +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
> +#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
> +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
> +#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
> +#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
> +
> +#ifndef __ASSEMBLY__
> +
> +struct mz_hdr {
> + uint16_t magic; /* MZ_MAGIC */
> + uint16_t lbsize; /* size of last used block */
> + uint16_t blocks; /* pages in file, 0x3 */
> + uint16_t relocs; /* relocations */
> + uint16_t hdrsize; /* header size in "paragraphs" */
> + uint16_t min_extra_pps; /* .bss */
> + uint16_t max_extra_pps; /* runtime limit for the arena size */
> + uint16_t ss; /* relative stack segment */
> + uint16_t sp; /* initial %sp register */
> + uint16_t checksum; /* word checksum */
> + uint16_t ip; /* initial %ip register */
> + uint16_t cs; /* initial %cs relative to load segment */
> + uint16_t reloc_table_offset; /* offset of the first relocation */
> + uint16_t overlay_num; /* overlay number. set to 0. */
> + uint16_t reserved0[4]; /* reserved */
> + uint16_t oem_id; /* oem identifier */
> + uint16_t oem_info; /* oem specific */
> + uint16_t reserved1[10]; /* reserved */
> + uint32_t peaddr; /* address of pe header */
> + char message[64]; /* message to print */
> +};
> +
> +struct mz_reloc {
> + uint16_t offset;
> + uint16_t segment;
> +};
> +
> +struct pe_hdr {
> + uint32_t magic; /* PE magic */
> + uint16_t machine; /* machine type */
> + uint16_t sections; /* number of sections */
> + uint32_t timestamp; /* time_t */
> + uint32_t symbol_table; /* symbol table offset */
> + uint32_t symbols; /* number of symbols */
> + uint16_t opt_hdr_size; /* size of optional header */
> + uint16_t flags; /* flags */
> +};
> +
> /* the fact that pe32 isn't padded where pe32+ is 64-bit means union won't
> * work right. vomit. */
> struct pe32_opt_hdr {
> @@ -243,52 +291,6 @@ struct section_header {
> uint32_t flags;
> };
>
> -/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
> -#define IMAGE_SCN_RESERVED_0 0x00000001
> -#define IMAGE_SCN_RESERVED_1 0x00000002
> -#define IMAGE_SCN_RESERVED_2 0x00000004
> -#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
> -#define IMAGE_SCN_RESERVED_3 0x00000010
> -#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
> -#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
> -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
> -#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
> -#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
> -#define IMAGE_SCN_RESERVED_4 0x00000400
> -#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
> -#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
> -#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
> -#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
> -#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
> -/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
> -#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
> -#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
> -#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
> -#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
> -/* and here they just stuck a 1-byte integer in the middle of a bitfield */
> -#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
> -#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
> -#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
> -#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
> -#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
> -#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
> -#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
> -#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
> -#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
> -#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
> -#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
> -#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
> -#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
> -#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
> -#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
> -#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
> -#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
> -#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
> -#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
> -#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
> -#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
> -#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
> -
> enum x64_coff_reloc_type {
> IMAGE_REL_AMD64_ABSOLUTE = 0,
> IMAGE_REL_AMD64_ADDR64,
> @@ -445,4 +447,6 @@ struct win_certificate {
> uint16_t cert_type;
> };
>
> +#endif /* !__ASSEMBLY__ */
> +
> #endif /* __LINUX_PE_H */
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 1/7] include: pe.h: allow for use in assembly
2017-02-06 16:33 ` [kernel-hardening] " Mark Rutland
@ 2017-02-06 16:40 ` Ard Biesheuvel
-1 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:40 UTC (permalink / raw)
To: linux-arm-kernel
On 6 February 2017 at 16:33, Mark Rutland <mark.rutland@arm.com> wrote:
> On Mon, Feb 06, 2017 at 04:24:29PM +0000, Ard Biesheuvel wrote:
>> From: Mark Rutland <mark.rutland@arm.com>
>>
>> Some of the definitions in include/linux/pe.h would be useful for the
>> EFI stub headers, where values are currently open-coded. Unfortunately
>> they cannot be used as some structures are also defined in pe.h without
>> !__ASSEMBLY__ guards.
>>
>> This patch moves the structure definitions into an #ifdef __ASSEMBLY__
>> block, so that the common value definitions can be used from assembly.
>>
>> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
>> ---
>> include/linux/pe.h | 174 ++++++++++----------
>> 1 file changed, 89 insertions(+), 85 deletions(-)
>
> Do remember that you need to add your own Signed-off-by for patches you
> pick up! :)
>
Ah yes, apologies for the sloppiness. I even modified the second patch
without making note of it in the commit log. Will fix that up
>
>>
>> diff --git a/include/linux/pe.h b/include/linux/pe.h
>> index e170b95e763b..a8a594117df3 100644
>> --- a/include/linux/pe.h
>> +++ b/include/linux/pe.h
>> @@ -23,34 +23,6 @@
>>
>> #define MZ_MAGIC 0x5a4d /* "MZ" */
>>
>> -struct mz_hdr {
>> - uint16_t magic; /* MZ_MAGIC */
>> - uint16_t lbsize; /* size of last used block */
>> - uint16_t blocks; /* pages in file, 0x3 */
>> - uint16_t relocs; /* relocations */
>> - uint16_t hdrsize; /* header size in "paragraphs" */
>> - uint16_t min_extra_pps; /* .bss */
>> - uint16_t max_extra_pps; /* runtime limit for the arena size */
>> - uint16_t ss; /* relative stack segment */
>> - uint16_t sp; /* initial %sp register */
>> - uint16_t checksum; /* word checksum */
>> - uint16_t ip; /* initial %ip register */
>> - uint16_t cs; /* initial %cs relative to load segment */
>> - uint16_t reloc_table_offset; /* offset of the first relocation */
>> - uint16_t overlay_num; /* overlay number. set to 0. */
>> - uint16_t reserved0[4]; /* reserved */
>> - uint16_t oem_id; /* oem identifier */
>> - uint16_t oem_info; /* oem specific */
>> - uint16_t reserved1[10]; /* reserved */
>> - uint32_t peaddr; /* address of pe header */
>> - char message[64]; /* message to print */
>> -};
>> -
>> -struct mz_reloc {
>> - uint16_t offset;
>> - uint16_t segment;
>> -};
>> -
>> #define PE_MAGIC 0x00004550 /* "PE\0\0" */
>> #define PE_OPT_MAGIC_PE32 0x010b
>> #define PE_OPT_MAGIC_PE32_ROM 0x0107
>> @@ -98,17 +70,6 @@ struct mz_reloc {
>> #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
>> #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
>>
>> -struct pe_hdr {
>> - uint32_t magic; /* PE magic */
>> - uint16_t machine; /* machine type */
>> - uint16_t sections; /* number of sections */
>> - uint32_t timestamp; /* time_t */
>> - uint32_t symbol_table; /* symbol table offset */
>> - uint32_t symbols; /* number of symbols */
>> - uint16_t opt_hdr_size; /* size of optional header */
>> - uint16_t flags; /* flags */
>> -};
>> -
>> #define IMAGE_FILE_OPT_ROM_MAGIC 0x107
>> #define IMAGE_FILE_OPT_PE32_MAGIC 0x10b
>> #define IMAGE_FILE_OPT_PE32_PLUS_MAGIC 0x20b
>> @@ -134,6 +95,93 @@ struct pe_hdr {
>> #define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000
>> #define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
>>
>> +/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
>> +#define IMAGE_SCN_RESERVED_0 0x00000001
>> +#define IMAGE_SCN_RESERVED_1 0x00000002
>> +#define IMAGE_SCN_RESERVED_2 0x00000004
>> +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
>> +#define IMAGE_SCN_RESERVED_3 0x00000010
>> +#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
>> +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
>> +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
>> +#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
>> +#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
>> +#define IMAGE_SCN_RESERVED_4 0x00000400
>> +#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
>> +#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
>> +#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
>> +#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
>> +#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
>> +/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
>> +#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
>> +#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
>> +#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
>> +#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
>> +/* and here they just stuck a 1-byte integer in the middle of a bitfield */
>> +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
>> +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
>> +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
>> +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
>> +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
>> +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
>> +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
>> +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
>> +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
>> +#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
>> +#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
>> +#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
>> +#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
>> +#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
>> +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
>> +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
>> +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
>> +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
>> +#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
>> +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
>> +#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
>> +#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
>> +
>> +#ifndef __ASSEMBLY__
>> +
>> +struct mz_hdr {
>> + uint16_t magic; /* MZ_MAGIC */
>> + uint16_t lbsize; /* size of last used block */
>> + uint16_t blocks; /* pages in file, 0x3 */
>> + uint16_t relocs; /* relocations */
>> + uint16_t hdrsize; /* header size in "paragraphs" */
>> + uint16_t min_extra_pps; /* .bss */
>> + uint16_t max_extra_pps; /* runtime limit for the arena size */
>> + uint16_t ss; /* relative stack segment */
>> + uint16_t sp; /* initial %sp register */
>> + uint16_t checksum; /* word checksum */
>> + uint16_t ip; /* initial %ip register */
>> + uint16_t cs; /* initial %cs relative to load segment */
>> + uint16_t reloc_table_offset; /* offset of the first relocation */
>> + uint16_t overlay_num; /* overlay number. set to 0. */
>> + uint16_t reserved0[4]; /* reserved */
>> + uint16_t oem_id; /* oem identifier */
>> + uint16_t oem_info; /* oem specific */
>> + uint16_t reserved1[10]; /* reserved */
>> + uint32_t peaddr; /* address of pe header */
>> + char message[64]; /* message to print */
>> +};
>> +
>> +struct mz_reloc {
>> + uint16_t offset;
>> + uint16_t segment;
>> +};
>> +
>> +struct pe_hdr {
>> + uint32_t magic; /* PE magic */
>> + uint16_t machine; /* machine type */
>> + uint16_t sections; /* number of sections */
>> + uint32_t timestamp; /* time_t */
>> + uint32_t symbol_table; /* symbol table offset */
>> + uint32_t symbols; /* number of symbols */
>> + uint16_t opt_hdr_size; /* size of optional header */
>> + uint16_t flags; /* flags */
>> +};
>> +
>> /* the fact that pe32 isn't padded where pe32+ is 64-bit means union won't
>> * work right. vomit. */
>> struct pe32_opt_hdr {
>> @@ -243,52 +291,6 @@ struct section_header {
>> uint32_t flags;
>> };
>>
>> -/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
>> -#define IMAGE_SCN_RESERVED_0 0x00000001
>> -#define IMAGE_SCN_RESERVED_1 0x00000002
>> -#define IMAGE_SCN_RESERVED_2 0x00000004
>> -#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
>> -#define IMAGE_SCN_RESERVED_3 0x00000010
>> -#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
>> -#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
>> -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
>> -#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
>> -#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
>> -#define IMAGE_SCN_RESERVED_4 0x00000400
>> -#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
>> -#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
>> -#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
>> -#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
>> -#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
>> -/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
>> -#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
>> -#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
>> -#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
>> -#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
>> -/* and here they just stuck a 1-byte integer in the middle of a bitfield */
>> -#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
>> -#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
>> -#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
>> -#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
>> -#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
>> -#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
>> -#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
>> -#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
>> -#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
>> -#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
>> -#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
>> -#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
>> -#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
>> -#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
>> -#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
>> -#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
>> -#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
>> -#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
>> -#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
>> -#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
>> -#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
>> -#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
>> -
>> enum x64_coff_reloc_type {
>> IMAGE_REL_AMD64_ABSOLUTE = 0,
>> IMAGE_REL_AMD64_ADDR64,
>> @@ -445,4 +447,6 @@ struct win_certificate {
>> uint16_t cert_type;
>> };
>>
>> +#endif /* !__ASSEMBLY__ */
>> +
>> #endif /* __LINUX_PE_H */
>> --
>> 2.7.4
>>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [kernel-hardening] Re: [PATCH 1/7] include: pe.h: allow for use in assembly
@ 2017-02-06 16:40 ` Ard Biesheuvel
0 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 16:40 UTC (permalink / raw)
To: Mark Rutland
Cc: linux-arm-kernel, Will Deacon, Catalin Marinas, Laura Abbott,
kernel-hardening, Leif Lindholm, Peter Jones
On 6 February 2017 at 16:33, Mark Rutland <mark.rutland@arm.com> wrote:
> On Mon, Feb 06, 2017 at 04:24:29PM +0000, Ard Biesheuvel wrote:
>> From: Mark Rutland <mark.rutland@arm.com>
>>
>> Some of the definitions in include/linux/pe.h would be useful for the
>> EFI stub headers, where values are currently open-coded. Unfortunately
>> they cannot be used as some structures are also defined in pe.h without
>> !__ASSEMBLY__ guards.
>>
>> This patch moves the structure definitions into an #ifdef __ASSEMBLY__
>> block, so that the common value definitions can be used from assembly.
>>
>> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
>> ---
>> include/linux/pe.h | 174 ++++++++++----------
>> 1 file changed, 89 insertions(+), 85 deletions(-)
>
> Do remember that you need to add your own Signed-off-by for patches you
> pick up! :)
>
Ah yes, apologies for the sloppiness. I even modified the second patch
without making note of it in the commit log. Will fix that up
>
>>
>> diff --git a/include/linux/pe.h b/include/linux/pe.h
>> index e170b95e763b..a8a594117df3 100644
>> --- a/include/linux/pe.h
>> +++ b/include/linux/pe.h
>> @@ -23,34 +23,6 @@
>>
>> #define MZ_MAGIC 0x5a4d /* "MZ" */
>>
>> -struct mz_hdr {
>> - uint16_t magic; /* MZ_MAGIC */
>> - uint16_t lbsize; /* size of last used block */
>> - uint16_t blocks; /* pages in file, 0x3 */
>> - uint16_t relocs; /* relocations */
>> - uint16_t hdrsize; /* header size in "paragraphs" */
>> - uint16_t min_extra_pps; /* .bss */
>> - uint16_t max_extra_pps; /* runtime limit for the arena size */
>> - uint16_t ss; /* relative stack segment */
>> - uint16_t sp; /* initial %sp register */
>> - uint16_t checksum; /* word checksum */
>> - uint16_t ip; /* initial %ip register */
>> - uint16_t cs; /* initial %cs relative to load segment */
>> - uint16_t reloc_table_offset; /* offset of the first relocation */
>> - uint16_t overlay_num; /* overlay number. set to 0. */
>> - uint16_t reserved0[4]; /* reserved */
>> - uint16_t oem_id; /* oem identifier */
>> - uint16_t oem_info; /* oem specific */
>> - uint16_t reserved1[10]; /* reserved */
>> - uint32_t peaddr; /* address of pe header */
>> - char message[64]; /* message to print */
>> -};
>> -
>> -struct mz_reloc {
>> - uint16_t offset;
>> - uint16_t segment;
>> -};
>> -
>> #define PE_MAGIC 0x00004550 /* "PE\0\0" */
>> #define PE_OPT_MAGIC_PE32 0x010b
>> #define PE_OPT_MAGIC_PE32_ROM 0x0107
>> @@ -98,17 +70,6 @@ struct mz_reloc {
>> #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
>> #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
>>
>> -struct pe_hdr {
>> - uint32_t magic; /* PE magic */
>> - uint16_t machine; /* machine type */
>> - uint16_t sections; /* number of sections */
>> - uint32_t timestamp; /* time_t */
>> - uint32_t symbol_table; /* symbol table offset */
>> - uint32_t symbols; /* number of symbols */
>> - uint16_t opt_hdr_size; /* size of optional header */
>> - uint16_t flags; /* flags */
>> -};
>> -
>> #define IMAGE_FILE_OPT_ROM_MAGIC 0x107
>> #define IMAGE_FILE_OPT_PE32_MAGIC 0x10b
>> #define IMAGE_FILE_OPT_PE32_PLUS_MAGIC 0x20b
>> @@ -134,6 +95,93 @@ struct pe_hdr {
>> #define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000
>> #define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
>>
>> +/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
>> +#define IMAGE_SCN_RESERVED_0 0x00000001
>> +#define IMAGE_SCN_RESERVED_1 0x00000002
>> +#define IMAGE_SCN_RESERVED_2 0x00000004
>> +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
>> +#define IMAGE_SCN_RESERVED_3 0x00000010
>> +#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
>> +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
>> +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
>> +#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
>> +#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
>> +#define IMAGE_SCN_RESERVED_4 0x00000400
>> +#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
>> +#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
>> +#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
>> +#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
>> +#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
>> +/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
>> +#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
>> +#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
>> +#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
>> +#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
>> +/* and here they just stuck a 1-byte integer in the middle of a bitfield */
>> +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
>> +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
>> +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
>> +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
>> +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
>> +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
>> +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
>> +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
>> +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
>> +#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
>> +#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
>> +#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
>> +#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
>> +#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
>> +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
>> +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
>> +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
>> +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
>> +#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
>> +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
>> +#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
>> +#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
>> +
>> +#ifndef __ASSEMBLY__
>> +
>> +struct mz_hdr {
>> + uint16_t magic; /* MZ_MAGIC */
>> + uint16_t lbsize; /* size of last used block */
>> + uint16_t blocks; /* pages in file, 0x3 */
>> + uint16_t relocs; /* relocations */
>> + uint16_t hdrsize; /* header size in "paragraphs" */
>> + uint16_t min_extra_pps; /* .bss */
>> + uint16_t max_extra_pps; /* runtime limit for the arena size */
>> + uint16_t ss; /* relative stack segment */
>> + uint16_t sp; /* initial %sp register */
>> + uint16_t checksum; /* word checksum */
>> + uint16_t ip; /* initial %ip register */
>> + uint16_t cs; /* initial %cs relative to load segment */
>> + uint16_t reloc_table_offset; /* offset of the first relocation */
>> + uint16_t overlay_num; /* overlay number. set to 0. */
>> + uint16_t reserved0[4]; /* reserved */
>> + uint16_t oem_id; /* oem identifier */
>> + uint16_t oem_info; /* oem specific */
>> + uint16_t reserved1[10]; /* reserved */
>> + uint32_t peaddr; /* address of pe header */
>> + char message[64]; /* message to print */
>> +};
>> +
>> +struct mz_reloc {
>> + uint16_t offset;
>> + uint16_t segment;
>> +};
>> +
>> +struct pe_hdr {
>> + uint32_t magic; /* PE magic */
>> + uint16_t machine; /* machine type */
>> + uint16_t sections; /* number of sections */
>> + uint32_t timestamp; /* time_t */
>> + uint32_t symbol_table; /* symbol table offset */
>> + uint32_t symbols; /* number of symbols */
>> + uint16_t opt_hdr_size; /* size of optional header */
>> + uint16_t flags; /* flags */
>> +};
>> +
>> /* the fact that pe32 isn't padded where pe32+ is 64-bit means union won't
>> * work right. vomit. */
>> struct pe32_opt_hdr {
>> @@ -243,52 +291,6 @@ struct section_header {
>> uint32_t flags;
>> };
>>
>> -/* they actually defined 0x00000000 as well, but I think we'll skip that one. */
>> -#define IMAGE_SCN_RESERVED_0 0x00000001
>> -#define IMAGE_SCN_RESERVED_1 0x00000002
>> -#define IMAGE_SCN_RESERVED_2 0x00000004
>> -#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* don't pad - obsolete */
>> -#define IMAGE_SCN_RESERVED_3 0x00000010
>> -#define IMAGE_SCN_CNT_CODE 0x00000020 /* .text */
>> -#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 /* .data */
>> -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 /* .bss */
>> -#define IMAGE_SCN_LNK_OTHER 0x00000100 /* reserved */
>> -#define IMAGE_SCN_LNK_INFO 0x00000200 /* .drectve comments */
>> -#define IMAGE_SCN_RESERVED_4 0x00000400
>> -#define IMAGE_SCN_LNK_REMOVE 0x00000800 /* .o only - scn to be rm'd*/
>> -#define IMAGE_SCN_LNK_COMDAT 0x00001000 /* .o only - COMDAT data */
>> -#define IMAGE_SCN_RESERVED_5 0x00002000 /* spec omits this */
>> -#define IMAGE_SCN_RESERVED_6 0x00004000 /* spec omits this */
>> -#define IMAGE_SCN_GPREL 0x00008000 /* global pointer referenced data */
>> -/* spec lists 0x20000 twice, I suspect they meant 0x10000 for one of them */
>> -#define IMAGE_SCN_MEM_PURGEABLE 0x00010000 /* reserved for "future" use */
>> -#define IMAGE_SCN_16BIT 0x00020000 /* reserved for "future" use */
>> -#define IMAGE_SCN_LOCKED 0x00040000 /* reserved for "future" use */
>> -#define IMAGE_SCN_PRELOAD 0x00080000 /* reserved for "future" use */
>> -/* and here they just stuck a 1-byte integer in the middle of a bitfield */
>> -#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 /* it does what it says on the box */
>> -#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
>> -#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
>> -#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
>> -#define IMAGE_SCN_ALIGN_16BYTES 0x00500000
>> -#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
>> -#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
>> -#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
>> -#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
>> -#define IMAGE_SCN_ALIGN_512BYTES 0x00a00000
>> -#define IMAGE_SCN_ALIGN_1024BYTES 0x00b00000
>> -#define IMAGE_SCN_ALIGN_2048BYTES 0x00c00000
>> -#define IMAGE_SCN_ALIGN_4096BYTES 0x00d00000
>> -#define IMAGE_SCN_ALIGN_8192BYTES 0x00e00000
>> -#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 /* extended relocations */
>> -#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 /* scn can be discarded */
>> -#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 /* cannot be cached */
>> -#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 /* not pageable */
>> -#define IMAGE_SCN_MEM_SHARED 0x10000000 /* can be shared */
>> -#define IMAGE_SCN_MEM_EXECUTE 0x20000000 /* can be executed as code */
>> -#define IMAGE_SCN_MEM_READ 0x40000000 /* readable */
>> -#define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */
>> -
>> enum x64_coff_reloc_type {
>> IMAGE_REL_AMD64_ABSOLUTE = 0,
>> IMAGE_REL_AMD64_ADDR64,
>> @@ -445,4 +447,6 @@ struct win_certificate {
>> uint16_t cert_type;
>> };
>>
>> +#endif /* !__ASSEMBLY__ */
>> +
>> #endif /* __LINUX_PE_H */
>> --
>> 2.7.4
>>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 3/7] arm64: efi: move EFI header and related data to a separate .S file
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 17:03 ` Mark Rutland
-1 siblings, 0 replies; 32+ messages in thread
From: Mark Rutland @ 2017-02-06 17:03 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 06, 2017 at 04:24:31PM +0000, Ard Biesheuvel wrote:
> In preparation of yet another round of modifications to the PE/COFF
> header, macroize it and move the definition into a separate source
> file.
I'm really not keen on portioning out bits of the arm64 header like
this.
The __jmp macro obscures the first few byes of the header, and we lose
the obvious relationship between the overlapping portions of the arm64
and PE/COFF headrs.
I think those portions which have a fixed offset from _head (which is at
least the overlapping PE/COFF and arm64 header bits) should stay in
head.S.
Can we factor out only the portions with a dynamic offset from the start
of the image? i.e. only pe_header and beyond?
Thanks,
Mark.
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> arch/arm64/kernel/efi-header.S | 182 ++++++++++++++++++++
> arch/arm64/kernel/head.S | 171 +-----------------
> 2 files changed, 186 insertions(+), 167 deletions(-)
>
> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
> new file mode 100644
> index 000000000000..8c8cd0a8192b
> --- /dev/null
> +++ b/arch/arm64/kernel/efi-header.S
> @@ -0,0 +1,182 @@
> +/*
> + * Copyright (C) 2013 - 2017 Linaro, Ltd.
> + * Copyright (C) 2013, 2014 Red Hat, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> + .macro __jmp, target
> +#ifdef CONFIG_EFI
> + /*
> + * This add instruction has no meaningful effect except that
> + * its opcode forms the magic "MZ" signature required by UEFI.
> + */
> + add x13, x18, #0x16
> + b \target
> +#else
> + b \target // branch to kernel start, magic
> + .long 0 // reserved
> +#endif
> + .endm
> +
> + .macro __EFI_HEADER
> +#ifdef CONFIG_EFI
> + .long pe_header - _head // Offset to the PE header.
> +#else
> + .word 0 // reserved
> +#endif
> +
> +#ifdef CONFIG_EFI
> + .align 3
> +pe_header:
> + .ascii "PE"
> + .short 0
> +coff_header:
> + .short 0xaa64 // AArch64
> + .short 2 // nr_sections
> + .long 0 // TimeDateStamp
> + .long 0 // PointerToSymbolTable
> + .long 1 // NumberOfSymbols
> + .short section_table - optional_header // SizeOfOptionalHeader
> + .short 0x206 // Characteristics.
> + // IMAGE_FILE_DEBUG_STRIPPED |
> + // IMAGE_FILE_EXECUTABLE_IMAGE |
> + // IMAGE_FILE_LINE_NUMS_STRIPPED
> +optional_header:
> + .short 0x20b // PE32+ format
> + .byte 0x02 // MajorLinkerVersion
> + .byte 0x14 // MinorLinkerVersion
> + .long _end - efi_header_end // SizeOfCode
> + .long 0 // SizeOfInitializedData
> + .long 0 // SizeOfUninitializedData
> + .long __efistub_entry - _head // AddressOfEntryPoint
> + .long efi_header_end - _head // BaseOfCode
> +
> +extra_header_fields:
> + .quad 0 // ImageBase
> + .long 0x1000 // SectionAlignment
> + .long PECOFF_FILE_ALIGNMENT // FileAlignment
> + .short 0 // MajorOperatingSystemVersion
> + .short 0 // MinorOperatingSystemVersion
> + .short 0 // MajorImageVersion
> + .short 0 // MinorImageVersion
> + .short 0 // MajorSubsystemVersion
> + .short 0 // MinorSubsystemVersion
> + .long 0 // Win32VersionValue
> +
> + .long _end - _head // SizeOfImage
> +
> + // Everything before the kernel image is considered part of the header
> + .long efi_header_end - _head // SizeOfHeaders
> + .long 0 // CheckSum
> + .short 0xa // Subsystem (EFI application)
> + .short 0 // DllCharacteristics
> + .quad 0 // SizeOfStackReserve
> + .quad 0 // SizeOfStackCommit
> + .quad 0 // SizeOfHeapReserve
> + .quad 0 // SizeOfHeapCommit
> + .long 0 // LoaderFlags
> + .long (section_table - .) / 8 // NumberOfRvaAndSizes
> +
> + .quad 0 // ExportTable
> + .quad 0 // ImportTable
> + .quad 0 // ResourceTable
> + .quad 0 // ExceptionTable
> + .quad 0 // CertificationTable
> + .quad 0 // BaseRelocationTable
> +
> +#ifdef CONFIG_DEBUG_EFI
> + .long efi_debug_table - _head // DebugTable
> + .long efi_debug_table_size
> +#endif
> +
> + // Section table
> +section_table:
> +
> + /*
> + * The EFI application loader requires a relocation section
> + * because EFI applications must be relocatable. This is a
> + * dummy section as far as we are concerned.
> + */
> + .ascii ".reloc"
> + .byte 0
> + .byte 0 // end of 0 padding of section name
> + .long 0
> + .long 0
> + .long 0 // SizeOfRawData
> + .long 0 // PointerToRawData
> + .long 0 // PointerToRelocations
> + .long 0 // PointerToLineNumbers
> + .short 0 // NumberOfRelocations
> + .short 0 // NumberOfLineNumbers
> + .long 0x42100040 // Characteristics (section flags)
> +
> +
> + .ascii ".text"
> + .byte 0
> + .byte 0
> + .byte 0 // end of 0 padding of section name
> + .long _end - efi_header_end // VirtualSize
> + .long efi_header_end - _head // VirtualAddress
> + .long _edata - efi_header_end // SizeOfRawData
> + .long efi_header_end - _head // PointerToRawData
> +
> + .long 0 // PointerToRelocations
> + .long 0 // PointerToLineNumbers
> + .short 0 // NumberOfRelocations
> + .short 0 // NumberOfLineNumbers
> + .long 0xe0500020 // Characteristics
> +
> +#ifdef CONFIG_DEBUG_EFI
> + /*
> + * The debug table is referenced via its Relative Virtual Address (RVA),
> + * which is only defined for those parts of the image that are covered
> + * by a section declaration. Since this header is not covered by any
> + * section, the debug table must be emitted elsewhere. So stick it in
> + * the .init.rodata section instead.
> + *
> + * Note that the EFI debug entry itself may legally have a zero RVA,
> + * which means we can simply put it right after the section headers.
> + */
> + __INITRODATA
> +
> + .align 2
> +efi_debug_table:
> + // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
> + .long 0 // Characteristics
> + .long 0 // TimeDateStamp
> + .short 0 // MajorVersion
> + .short 0 // MinorVersion
> + .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
> + .long efi_debug_entry_size // SizeOfData
> + .long 0 // RVA
> + .long efi_debug_entry - _head // FileOffset
> +
> + .set efi_debug_table_size, . - efi_debug_table
> + .previous
> +
> +efi_debug_entry:
> + // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
> + .ascii "NB10" // Signature
> + .long 0 // Unknown
> + .long 0 // Unknown2
> + .long 0 // Unknown3
> +
> + .asciz VMLINUX_PATH
> +
> + .set efi_debug_entry_size, . - efi_debug_entry
> +#endif
> +
> + /*
> + * EFI will load .text onwards at the 4k section alignment
> + * described in the PE/COFF header. To ensure that instruction
> + * sequences using an adrp and a :lo12: immediate will function
> + * correctly at this alignment, we must ensure that .text is
> + * placed at a 4k boundary in the Image to begin with.
> + */
> + .align 12
> +efi_header_end:
> +#endif
> + .endm
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index c6cc82ec190b..aca9b184035a 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -42,6 +42,8 @@
> #include <asm/thread_info.h>
> #include <asm/virt.h>
>
> +#include "efi-header.S"
> +
> #define __PHYS_OFFSET (KERNEL_START - TEXT_OFFSET)
>
> #if (TEXT_OFFSET & 0xfff) != 0
> @@ -72,17 +74,7 @@ _head:
> /*
> * DO NOT MODIFY. Image header expected by Linux boot-loaders.
> */
> -#ifdef CONFIG_EFI
> - /*
> - * This add instruction has no meaningful effect except that
> - * its opcode forms the magic "MZ" signature required by UEFI.
> - */
> - add x13, x18, #0x16
> - b stext
> -#else
> - b stext // branch to kernel start, magic
> - .long 0 // reserved
> -#endif
> + __jmp stext // Executable code
> le64sym _kernel_offset_le // Image load offset from start of RAM, little-endian
> le64sym _kernel_size_le // Effective size of kernel image, little-endian
> le64sym _kernel_flags_le // Informative flags, little-endian
> @@ -93,163 +85,8 @@ _head:
> .byte 0x52
> .byte 0x4d
> .byte 0x64
> -#ifdef CONFIG_EFI
> - .long pe_header - _head // Offset to the PE header.
> -#else
> - .word 0 // reserved
> -#endif
> -
> -#ifdef CONFIG_EFI
> - .align 3
> -pe_header:
> - .ascii "PE"
> - .short 0
> -coff_header:
> - .short 0xaa64 // AArch64
> - .short 2 // nr_sections
> - .long 0 // TimeDateStamp
> - .long 0 // PointerToSymbolTable
> - .long 1 // NumberOfSymbols
> - .short section_table - optional_header // SizeOfOptionalHeader
> - .short 0x206 // Characteristics.
> - // IMAGE_FILE_DEBUG_STRIPPED |
> - // IMAGE_FILE_EXECUTABLE_IMAGE |
> - // IMAGE_FILE_LINE_NUMS_STRIPPED
> -optional_header:
> - .short 0x20b // PE32+ format
> - .byte 0x02 // MajorLinkerVersion
> - .byte 0x14 // MinorLinkerVersion
> - .long _end - efi_header_end // SizeOfCode
> - .long 0 // SizeOfInitializedData
> - .long 0 // SizeOfUninitializedData
> - .long __efistub_entry - _head // AddressOfEntryPoint
> - .long efi_header_end - _head // BaseOfCode
> -
> -extra_header_fields:
> - .quad 0 // ImageBase
> - .long 0x1000 // SectionAlignment
> - .long PECOFF_FILE_ALIGNMENT // FileAlignment
> - .short 0 // MajorOperatingSystemVersion
> - .short 0 // MinorOperatingSystemVersion
> - .short 0 // MajorImageVersion
> - .short 0 // MinorImageVersion
> - .short 0 // MajorSubsystemVersion
> - .short 0 // MinorSubsystemVersion
> - .long 0 // Win32VersionValue
> -
> - .long _end - _head // SizeOfImage
> -
> - // Everything before the kernel image is considered part of the header
> - .long efi_header_end - _head // SizeOfHeaders
> - .long 0 // CheckSum
> - .short 0xa // Subsystem (EFI application)
> - .short 0 // DllCharacteristics
> - .quad 0 // SizeOfStackReserve
> - .quad 0 // SizeOfStackCommit
> - .quad 0 // SizeOfHeapReserve
> - .quad 0 // SizeOfHeapCommit
> - .long 0 // LoaderFlags
> - .long (section_table - .) / 8 // NumberOfRvaAndSizes
> -
> - .quad 0 // ExportTable
> - .quad 0 // ImportTable
> - .quad 0 // ResourceTable
> - .quad 0 // ExceptionTable
> - .quad 0 // CertificationTable
> - .quad 0 // BaseRelocationTable
> -
> -#ifdef CONFIG_DEBUG_EFI
> - .long efi_debug_table - _head // DebugTable
> - .long efi_debug_table_size
> -#endif
> -
> - // Section table
> -section_table:
>
> - /*
> - * The EFI application loader requires a relocation section
> - * because EFI applications must be relocatable. This is a
> - * dummy section as far as we are concerned.
> - */
> - .ascii ".reloc"
> - .byte 0
> - .byte 0 // end of 0 padding of section name
> - .long 0
> - .long 0
> - .long 0 // SizeOfRawData
> - .long 0 // PointerToRawData
> - .long 0 // PointerToRelocations
> - .long 0 // PointerToLineNumbers
> - .short 0 // NumberOfRelocations
> - .short 0 // NumberOfLineNumbers
> - .long 0x42100040 // Characteristics (section flags)
> -
> -
> - .ascii ".text"
> - .byte 0
> - .byte 0
> - .byte 0 // end of 0 padding of section name
> - .long _end - efi_header_end // VirtualSize
> - .long efi_header_end - _head // VirtualAddress
> - .long _edata - efi_header_end // SizeOfRawData
> - .long efi_header_end - _head // PointerToRawData
> -
> - .long 0 // PointerToRelocations (0 for executables)
> - .long 0 // PointerToLineNumbers (0 for executables)
> - .short 0 // NumberOfRelocations (0 for executables)
> - .short 0 // NumberOfLineNumbers (0 for executables)
> - .long 0xe0500020 // Characteristics (section flags)
> -
> -#ifdef CONFIG_DEBUG_EFI
> - /*
> - * The debug table is referenced via its Relative Virtual Address (RVA),
> - * which is only defined for those parts of the image that are covered
> - * by a section declaration. Since this header is not covered by any
> - * section, the debug table must be emitted elsewhere. So stick it in
> - * the .init.rodata section instead.
> - *
> - * Note that the EFI debug entry itself may legally have a zero RVA,
> - * which means we can simply put it right after the section headers.
> - */
> - __INITRODATA
> -
> - .align 2
> -efi_debug_table:
> - // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
> - .long 0 // Characteristics
> - .long 0 // TimeDateStamp
> - .short 0 // MajorVersion
> - .short 0 // MinorVersion
> - .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
> - .long efi_debug_entry_size // SizeOfData
> - .long 0 // RVA
> - .long efi_debug_entry - _head // FileOffset
> -
> - .set efi_debug_table_size, . - efi_debug_table
> - .previous
> -
> -efi_debug_entry:
> - // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
> - .ascii "NB10" // Signature
> - .long 0 // Unknown
> - .long 0 // Unknown2
> - .long 0 // Unknown3
> -
> - .asciz VMLINUX_PATH
> -
> - .set efi_debug_entry_size, . - efi_debug_entry
> -#endif
> -
> - /*
> - * EFI will load .text onwards at the 4k section alignment
> - * described in the PE/COFF header. To ensure that instruction
> - * sequences using an adrp and a :lo12: immediate will function
> - * correctly at this alignment, we must ensure that .text is
> - * placed at a 4k boundary in the Image to begin with.
> - */
> - .align 12
> -efi_header_end:
> -#endif
> + __EFI_HEADER
>
> __INIT
>
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [kernel-hardening] Re: [PATCH 3/7] arm64: efi: move EFI header and related data to a separate .S file
@ 2017-02-06 17:03 ` Mark Rutland
0 siblings, 0 replies; 32+ messages in thread
From: Mark Rutland @ 2017-02-06 17:03 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-arm-kernel, will.deacon, catalin.marinas, labbott,
kernel-hardening, leif.lindholm, pjones
On Mon, Feb 06, 2017 at 04:24:31PM +0000, Ard Biesheuvel wrote:
> In preparation of yet another round of modifications to the PE/COFF
> header, macroize it and move the definition into a separate source
> file.
I'm really not keen on portioning out bits of the arm64 header like
this.
The __jmp macro obscures the first few byes of the header, and we lose
the obvious relationship between the overlapping portions of the arm64
and PE/COFF headrs.
I think those portions which have a fixed offset from _head (which is at
least the overlapping PE/COFF and arm64 header bits) should stay in
head.S.
Can we factor out only the portions with a dynamic offset from the start
of the image? i.e. only pe_header and beyond?
Thanks,
Mark.
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> arch/arm64/kernel/efi-header.S | 182 ++++++++++++++++++++
> arch/arm64/kernel/head.S | 171 +-----------------
> 2 files changed, 186 insertions(+), 167 deletions(-)
>
> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
> new file mode 100644
> index 000000000000..8c8cd0a8192b
> --- /dev/null
> +++ b/arch/arm64/kernel/efi-header.S
> @@ -0,0 +1,182 @@
> +/*
> + * Copyright (C) 2013 - 2017 Linaro, Ltd.
> + * Copyright (C) 2013, 2014 Red Hat, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> + .macro __jmp, target
> +#ifdef CONFIG_EFI
> + /*
> + * This add instruction has no meaningful effect except that
> + * its opcode forms the magic "MZ" signature required by UEFI.
> + */
> + add x13, x18, #0x16
> + b \target
> +#else
> + b \target // branch to kernel start, magic
> + .long 0 // reserved
> +#endif
> + .endm
> +
> + .macro __EFI_HEADER
> +#ifdef CONFIG_EFI
> + .long pe_header - _head // Offset to the PE header.
> +#else
> + .word 0 // reserved
> +#endif
> +
> +#ifdef CONFIG_EFI
> + .align 3
> +pe_header:
> + .ascii "PE"
> + .short 0
> +coff_header:
> + .short 0xaa64 // AArch64
> + .short 2 // nr_sections
> + .long 0 // TimeDateStamp
> + .long 0 // PointerToSymbolTable
> + .long 1 // NumberOfSymbols
> + .short section_table - optional_header // SizeOfOptionalHeader
> + .short 0x206 // Characteristics.
> + // IMAGE_FILE_DEBUG_STRIPPED |
> + // IMAGE_FILE_EXECUTABLE_IMAGE |
> + // IMAGE_FILE_LINE_NUMS_STRIPPED
> +optional_header:
> + .short 0x20b // PE32+ format
> + .byte 0x02 // MajorLinkerVersion
> + .byte 0x14 // MinorLinkerVersion
> + .long _end - efi_header_end // SizeOfCode
> + .long 0 // SizeOfInitializedData
> + .long 0 // SizeOfUninitializedData
> + .long __efistub_entry - _head // AddressOfEntryPoint
> + .long efi_header_end - _head // BaseOfCode
> +
> +extra_header_fields:
> + .quad 0 // ImageBase
> + .long 0x1000 // SectionAlignment
> + .long PECOFF_FILE_ALIGNMENT // FileAlignment
> + .short 0 // MajorOperatingSystemVersion
> + .short 0 // MinorOperatingSystemVersion
> + .short 0 // MajorImageVersion
> + .short 0 // MinorImageVersion
> + .short 0 // MajorSubsystemVersion
> + .short 0 // MinorSubsystemVersion
> + .long 0 // Win32VersionValue
> +
> + .long _end - _head // SizeOfImage
> +
> + // Everything before the kernel image is considered part of the header
> + .long efi_header_end - _head // SizeOfHeaders
> + .long 0 // CheckSum
> + .short 0xa // Subsystem (EFI application)
> + .short 0 // DllCharacteristics
> + .quad 0 // SizeOfStackReserve
> + .quad 0 // SizeOfStackCommit
> + .quad 0 // SizeOfHeapReserve
> + .quad 0 // SizeOfHeapCommit
> + .long 0 // LoaderFlags
> + .long (section_table - .) / 8 // NumberOfRvaAndSizes
> +
> + .quad 0 // ExportTable
> + .quad 0 // ImportTable
> + .quad 0 // ResourceTable
> + .quad 0 // ExceptionTable
> + .quad 0 // CertificationTable
> + .quad 0 // BaseRelocationTable
> +
> +#ifdef CONFIG_DEBUG_EFI
> + .long efi_debug_table - _head // DebugTable
> + .long efi_debug_table_size
> +#endif
> +
> + // Section table
> +section_table:
> +
> + /*
> + * The EFI application loader requires a relocation section
> + * because EFI applications must be relocatable. This is a
> + * dummy section as far as we are concerned.
> + */
> + .ascii ".reloc"
> + .byte 0
> + .byte 0 // end of 0 padding of section name
> + .long 0
> + .long 0
> + .long 0 // SizeOfRawData
> + .long 0 // PointerToRawData
> + .long 0 // PointerToRelocations
> + .long 0 // PointerToLineNumbers
> + .short 0 // NumberOfRelocations
> + .short 0 // NumberOfLineNumbers
> + .long 0x42100040 // Characteristics (section flags)
> +
> +
> + .ascii ".text"
> + .byte 0
> + .byte 0
> + .byte 0 // end of 0 padding of section name
> + .long _end - efi_header_end // VirtualSize
> + .long efi_header_end - _head // VirtualAddress
> + .long _edata - efi_header_end // SizeOfRawData
> + .long efi_header_end - _head // PointerToRawData
> +
> + .long 0 // PointerToRelocations
> + .long 0 // PointerToLineNumbers
> + .short 0 // NumberOfRelocations
> + .short 0 // NumberOfLineNumbers
> + .long 0xe0500020 // Characteristics
> +
> +#ifdef CONFIG_DEBUG_EFI
> + /*
> + * The debug table is referenced via its Relative Virtual Address (RVA),
> + * which is only defined for those parts of the image that are covered
> + * by a section declaration. Since this header is not covered by any
> + * section, the debug table must be emitted elsewhere. So stick it in
> + * the .init.rodata section instead.
> + *
> + * Note that the EFI debug entry itself may legally have a zero RVA,
> + * which means we can simply put it right after the section headers.
> + */
> + __INITRODATA
> +
> + .align 2
> +efi_debug_table:
> + // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
> + .long 0 // Characteristics
> + .long 0 // TimeDateStamp
> + .short 0 // MajorVersion
> + .short 0 // MinorVersion
> + .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
> + .long efi_debug_entry_size // SizeOfData
> + .long 0 // RVA
> + .long efi_debug_entry - _head // FileOffset
> +
> + .set efi_debug_table_size, . - efi_debug_table
> + .previous
> +
> +efi_debug_entry:
> + // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
> + .ascii "NB10" // Signature
> + .long 0 // Unknown
> + .long 0 // Unknown2
> + .long 0 // Unknown3
> +
> + .asciz VMLINUX_PATH
> +
> + .set efi_debug_entry_size, . - efi_debug_entry
> +#endif
> +
> + /*
> + * EFI will load .text onwards at the 4k section alignment
> + * described in the PE/COFF header. To ensure that instruction
> + * sequences using an adrp and a :lo12: immediate will function
> + * correctly at this alignment, we must ensure that .text is
> + * placed at a 4k boundary in the Image to begin with.
> + */
> + .align 12
> +efi_header_end:
> +#endif
> + .endm
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index c6cc82ec190b..aca9b184035a 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -42,6 +42,8 @@
> #include <asm/thread_info.h>
> #include <asm/virt.h>
>
> +#include "efi-header.S"
> +
> #define __PHYS_OFFSET (KERNEL_START - TEXT_OFFSET)
>
> #if (TEXT_OFFSET & 0xfff) != 0
> @@ -72,17 +74,7 @@ _head:
> /*
> * DO NOT MODIFY. Image header expected by Linux boot-loaders.
> */
> -#ifdef CONFIG_EFI
> - /*
> - * This add instruction has no meaningful effect except that
> - * its opcode forms the magic "MZ" signature required by UEFI.
> - */
> - add x13, x18, #0x16
> - b stext
> -#else
> - b stext // branch to kernel start, magic
> - .long 0 // reserved
> -#endif
> + __jmp stext // Executable code
> le64sym _kernel_offset_le // Image load offset from start of RAM, little-endian
> le64sym _kernel_size_le // Effective size of kernel image, little-endian
> le64sym _kernel_flags_le // Informative flags, little-endian
> @@ -93,163 +85,8 @@ _head:
> .byte 0x52
> .byte 0x4d
> .byte 0x64
> -#ifdef CONFIG_EFI
> - .long pe_header - _head // Offset to the PE header.
> -#else
> - .word 0 // reserved
> -#endif
> -
> -#ifdef CONFIG_EFI
> - .align 3
> -pe_header:
> - .ascii "PE"
> - .short 0
> -coff_header:
> - .short 0xaa64 // AArch64
> - .short 2 // nr_sections
> - .long 0 // TimeDateStamp
> - .long 0 // PointerToSymbolTable
> - .long 1 // NumberOfSymbols
> - .short section_table - optional_header // SizeOfOptionalHeader
> - .short 0x206 // Characteristics.
> - // IMAGE_FILE_DEBUG_STRIPPED |
> - // IMAGE_FILE_EXECUTABLE_IMAGE |
> - // IMAGE_FILE_LINE_NUMS_STRIPPED
> -optional_header:
> - .short 0x20b // PE32+ format
> - .byte 0x02 // MajorLinkerVersion
> - .byte 0x14 // MinorLinkerVersion
> - .long _end - efi_header_end // SizeOfCode
> - .long 0 // SizeOfInitializedData
> - .long 0 // SizeOfUninitializedData
> - .long __efistub_entry - _head // AddressOfEntryPoint
> - .long efi_header_end - _head // BaseOfCode
> -
> -extra_header_fields:
> - .quad 0 // ImageBase
> - .long 0x1000 // SectionAlignment
> - .long PECOFF_FILE_ALIGNMENT // FileAlignment
> - .short 0 // MajorOperatingSystemVersion
> - .short 0 // MinorOperatingSystemVersion
> - .short 0 // MajorImageVersion
> - .short 0 // MinorImageVersion
> - .short 0 // MajorSubsystemVersion
> - .short 0 // MinorSubsystemVersion
> - .long 0 // Win32VersionValue
> -
> - .long _end - _head // SizeOfImage
> -
> - // Everything before the kernel image is considered part of the header
> - .long efi_header_end - _head // SizeOfHeaders
> - .long 0 // CheckSum
> - .short 0xa // Subsystem (EFI application)
> - .short 0 // DllCharacteristics
> - .quad 0 // SizeOfStackReserve
> - .quad 0 // SizeOfStackCommit
> - .quad 0 // SizeOfHeapReserve
> - .quad 0 // SizeOfHeapCommit
> - .long 0 // LoaderFlags
> - .long (section_table - .) / 8 // NumberOfRvaAndSizes
> -
> - .quad 0 // ExportTable
> - .quad 0 // ImportTable
> - .quad 0 // ResourceTable
> - .quad 0 // ExceptionTable
> - .quad 0 // CertificationTable
> - .quad 0 // BaseRelocationTable
> -
> -#ifdef CONFIG_DEBUG_EFI
> - .long efi_debug_table - _head // DebugTable
> - .long efi_debug_table_size
> -#endif
> -
> - // Section table
> -section_table:
>
> - /*
> - * The EFI application loader requires a relocation section
> - * because EFI applications must be relocatable. This is a
> - * dummy section as far as we are concerned.
> - */
> - .ascii ".reloc"
> - .byte 0
> - .byte 0 // end of 0 padding of section name
> - .long 0
> - .long 0
> - .long 0 // SizeOfRawData
> - .long 0 // PointerToRawData
> - .long 0 // PointerToRelocations
> - .long 0 // PointerToLineNumbers
> - .short 0 // NumberOfRelocations
> - .short 0 // NumberOfLineNumbers
> - .long 0x42100040 // Characteristics (section flags)
> -
> -
> - .ascii ".text"
> - .byte 0
> - .byte 0
> - .byte 0 // end of 0 padding of section name
> - .long _end - efi_header_end // VirtualSize
> - .long efi_header_end - _head // VirtualAddress
> - .long _edata - efi_header_end // SizeOfRawData
> - .long efi_header_end - _head // PointerToRawData
> -
> - .long 0 // PointerToRelocations (0 for executables)
> - .long 0 // PointerToLineNumbers (0 for executables)
> - .short 0 // NumberOfRelocations (0 for executables)
> - .short 0 // NumberOfLineNumbers (0 for executables)
> - .long 0xe0500020 // Characteristics (section flags)
> -
> -#ifdef CONFIG_DEBUG_EFI
> - /*
> - * The debug table is referenced via its Relative Virtual Address (RVA),
> - * which is only defined for those parts of the image that are covered
> - * by a section declaration. Since this header is not covered by any
> - * section, the debug table must be emitted elsewhere. So stick it in
> - * the .init.rodata section instead.
> - *
> - * Note that the EFI debug entry itself may legally have a zero RVA,
> - * which means we can simply put it right after the section headers.
> - */
> - __INITRODATA
> -
> - .align 2
> -efi_debug_table:
> - // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
> - .long 0 // Characteristics
> - .long 0 // TimeDateStamp
> - .short 0 // MajorVersion
> - .short 0 // MinorVersion
> - .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
> - .long efi_debug_entry_size // SizeOfData
> - .long 0 // RVA
> - .long efi_debug_entry - _head // FileOffset
> -
> - .set efi_debug_table_size, . - efi_debug_table
> - .previous
> -
> -efi_debug_entry:
> - // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
> - .ascii "NB10" // Signature
> - .long 0 // Unknown
> - .long 0 // Unknown2
> - .long 0 // Unknown3
> -
> - .asciz VMLINUX_PATH
> -
> - .set efi_debug_entry_size, . - efi_debug_entry
> -#endif
> -
> - /*
> - * EFI will load .text onwards at the 4k section alignment
> - * described in the PE/COFF header. To ensure that instruction
> - * sequences using an adrp and a :lo12: immediate will function
> - * correctly at this alignment, we must ensure that .text is
> - * placed at a 4k boundary in the Image to begin with.
> - */
> - .align 12
> -efi_header_end:
> -#endif
> + __EFI_HEADER
>
> __INIT
>
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 4/7] arm64: efi: ensure that the PE/COFF header pointer appears at offset 0x3c
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 17:05 ` Mark Rutland
-1 siblings, 0 replies; 32+ messages in thread
From: Mark Rutland @ 2017-02-06 17:05 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 06, 2017 at 04:24:32PM +0000, Ard Biesheuvel wrote:
> Use a .org directive to ensure that the PE/COFF header pointer appears
> at offset 0x3c. Since the EFI header is now emitted using a macro, this
> helps ensure that the invocation of the macro remains at the correct
> offset.
>
> At the same time, collapse two adjacent #ifdef CONFIG_EFI blocks into one,
> and replace .word with .long (which are equivalent, but the former is
> never used elsewhere)
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
As with patch 3, I would very much prefer that we left these bits in
head.S.
Thanks,
Mark.
> ---
> arch/arm64/kernel/efi-header.S | 14 ++++++++------
> 1 file changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
> index 8c8cd0a8192b..74a25c09a1b8 100644
> --- a/arch/arm64/kernel/efi-header.S
> +++ b/arch/arm64/kernel/efi-header.S
> @@ -22,14 +22,16 @@
> .endm
>
> .macro __EFI_HEADER
> -#ifdef CONFIG_EFI
> - .long pe_header - _head // Offset to the PE header.
> +#ifndef CONFIG_EFI
> + .long 0 // reserved
> #else
> - .word 0 // reserved
> -#endif
> + /*
> + * PE/COFF requires the offset to the PE header
> + * to be stored at offset 0x3c into the file.
> + */
> + .org _head + 0x3c
> + .long pe_header - _head // Offset to the PE header.
>
> -#ifdef CONFIG_EFI
> - .align 3
> pe_header:
> .ascii "PE"
> .short 0
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [kernel-hardening] Re: [PATCH 4/7] arm64: efi: ensure that the PE/COFF header pointer appears at offset 0x3c
@ 2017-02-06 17:05 ` Mark Rutland
0 siblings, 0 replies; 32+ messages in thread
From: Mark Rutland @ 2017-02-06 17:05 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-arm-kernel, will.deacon, catalin.marinas, labbott,
kernel-hardening, leif.lindholm, pjones
On Mon, Feb 06, 2017 at 04:24:32PM +0000, Ard Biesheuvel wrote:
> Use a .org directive to ensure that the PE/COFF header pointer appears
> at offset 0x3c. Since the EFI header is now emitted using a macro, this
> helps ensure that the invocation of the macro remains at the correct
> offset.
>
> At the same time, collapse two adjacent #ifdef CONFIG_EFI blocks into one,
> and replace .word with .long (which are equivalent, but the former is
> never used elsewhere)
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
As with patch 3, I would very much prefer that we left these bits in
head.S.
Thanks,
Mark.
> ---
> arch/arm64/kernel/efi-header.S | 14 ++++++++------
> 1 file changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
> index 8c8cd0a8192b..74a25c09a1b8 100644
> --- a/arch/arm64/kernel/efi-header.S
> +++ b/arch/arm64/kernel/efi-header.S
> @@ -22,14 +22,16 @@
> .endm
>
> .macro __EFI_HEADER
> -#ifdef CONFIG_EFI
> - .long pe_header - _head // Offset to the PE header.
> +#ifndef CONFIG_EFI
> + .long 0 // reserved
> #else
> - .word 0 // reserved
> -#endif
> + /*
> + * PE/COFF requires the offset to the PE header
> + * to be stored at offset 0x3c into the file.
> + */
> + .org _head + 0x3c
> + .long pe_header - _head // Offset to the PE header.
>
> -#ifdef CONFIG_EFI
> - .align 3
> pe_header:
> .ascii "PE"
> .short 0
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 5/7] arm64: efi: remove pointless dummy .reloc section
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 17:06 ` Mark Rutland
-1 siblings, 0 replies; 32+ messages in thread
From: Mark Rutland @ 2017-02-06 17:06 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 06, 2017 at 04:24:33PM +0000, Ard Biesheuvel wrote:
> The kernel's EFI PE/COFF header contains a dummy .reloc section, and
> an explanatory comment that claims that this is required for the EFI
> application loader to accept the Image as a relocatable image (i.e.,
> one that can be loaded at any offset and fixed up in place)
>
> This was inherited from the x86 implementation, which has elaborate host
> tooling to mangle the PE/COFF header post-link time, and which populates
> the .reloc section with a single dummy base relocation. On ARM, no such
> tooling exists, and the .reloc section remains empty, and is never even
> exposed via the BaseRelocationTable directory entry, which is where the
> PE/COFF loader looks for it.
>
> The PE/COFF spec is unclear about relocatable images that do not require
> any fixups, but the EDK2 implementation, which is the de facto reference
> for PE/COFF in the UEFI space, clearly does not care, and explicitly
> mentions (in a comment) that relocatable images with no base relocations
> are perfectly fine, as long as they don't have the RELOCS_STRIPPED
> attribute set (which is not the case for our PE/COFF image)
>
> So simply remove the .reloc section altogether.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
I don't have anything against this patch, so FWIW:
Acked-by: Mark Rutland <mark.rutland@arm.com>
Thanks,
Mark.
> ---
> arch/arm64/kernel/efi-header.S | 22 +-------------------
> 1 file changed, 1 insertion(+), 21 deletions(-)
>
> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
> index 74a25c09a1b8..35b11654ecc5 100644
> --- a/arch/arm64/kernel/efi-header.S
> +++ b/arch/arm64/kernel/efi-header.S
> @@ -37,7 +37,7 @@ pe_header:
> .short 0
> coff_header:
> .short 0xaa64 // AArch64
> - .short 2 // nr_sections
> + .short 1 // nr_sections
> .long 0 // TimeDateStamp
> .long 0 // PointerToSymbolTable
> .long 1 // NumberOfSymbols
> @@ -96,26 +96,6 @@ extra_header_fields:
>
> // Section table
> section_table:
> -
> - /*
> - * The EFI application loader requires a relocation section
> - * because EFI applications must be relocatable. This is a
> - * dummy section as far as we are concerned.
> - */
> - .ascii ".reloc"
> - .byte 0
> - .byte 0 // end of 0 padding of section name
> - .long 0
> - .long 0
> - .long 0 // SizeOfRawData
> - .long 0 // PointerToRawData
> - .long 0 // PointerToRelocations
> - .long 0 // PointerToLineNumbers
> - .short 0 // NumberOfRelocations
> - .short 0 // NumberOfLineNumbers
> - .long 0x42100040 // Characteristics (section flags)
> -
> -
> .ascii ".text"
> .byte 0
> .byte 0
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [kernel-hardening] Re: [PATCH 5/7] arm64: efi: remove pointless dummy .reloc section
@ 2017-02-06 17:06 ` Mark Rutland
0 siblings, 0 replies; 32+ messages in thread
From: Mark Rutland @ 2017-02-06 17:06 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-arm-kernel, will.deacon, catalin.marinas, labbott,
kernel-hardening, leif.lindholm, pjones
On Mon, Feb 06, 2017 at 04:24:33PM +0000, Ard Biesheuvel wrote:
> The kernel's EFI PE/COFF header contains a dummy .reloc section, and
> an explanatory comment that claims that this is required for the EFI
> application loader to accept the Image as a relocatable image (i.e.,
> one that can be loaded at any offset and fixed up in place)
>
> This was inherited from the x86 implementation, which has elaborate host
> tooling to mangle the PE/COFF header post-link time, and which populates
> the .reloc section with a single dummy base relocation. On ARM, no such
> tooling exists, and the .reloc section remains empty, and is never even
> exposed via the BaseRelocationTable directory entry, which is where the
> PE/COFF loader looks for it.
>
> The PE/COFF spec is unclear about relocatable images that do not require
> any fixups, but the EDK2 implementation, which is the de facto reference
> for PE/COFF in the UEFI space, clearly does not care, and explicitly
> mentions (in a comment) that relocatable images with no base relocations
> are perfectly fine, as long as they don't have the RELOCS_STRIPPED
> attribute set (which is not the case for our PE/COFF image)
>
> So simply remove the .reloc section altogether.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
I don't have anything against this patch, so FWIW:
Acked-by: Mark Rutland <mark.rutland@arm.com>
Thanks,
Mark.
> ---
> arch/arm64/kernel/efi-header.S | 22 +-------------------
> 1 file changed, 1 insertion(+), 21 deletions(-)
>
> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
> index 74a25c09a1b8..35b11654ecc5 100644
> --- a/arch/arm64/kernel/efi-header.S
> +++ b/arch/arm64/kernel/efi-header.S
> @@ -37,7 +37,7 @@ pe_header:
> .short 0
> coff_header:
> .short 0xaa64 // AArch64
> - .short 2 // nr_sections
> + .short 1 // nr_sections
> .long 0 // TimeDateStamp
> .long 0 // PointerToSymbolTable
> .long 1 // NumberOfSymbols
> @@ -96,26 +96,6 @@ extra_header_fields:
>
> // Section table
> section_table:
> -
> - /*
> - * The EFI application loader requires a relocation section
> - * because EFI applications must be relocatable. This is a
> - * dummy section as far as we are concerned.
> - */
> - .ascii ".reloc"
> - .byte 0
> - .byte 0 // end of 0 padding of section name
> - .long 0
> - .long 0
> - .long 0 // SizeOfRawData
> - .long 0 // PointerToRawData
> - .long 0 // PointerToRelocations
> - .long 0 // PointerToLineNumbers
> - .short 0 // NumberOfRelocations
> - .short 0 // NumberOfLineNumbers
> - .long 0x42100040 // Characteristics (section flags)
> -
> -
> .ascii ".text"
> .byte 0
> .byte 0
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 3/7] arm64: efi: move EFI header and related data to a separate .S file
2017-02-06 17:03 ` [kernel-hardening] " Mark Rutland
@ 2017-02-06 17:07 ` Ard Biesheuvel
-1 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 17:07 UTC (permalink / raw)
To: linux-arm-kernel
On 6 February 2017 at 17:03, Mark Rutland <mark.rutland@arm.com> wrote:
> On Mon, Feb 06, 2017 at 04:24:31PM +0000, Ard Biesheuvel wrote:
>> In preparation of yet another round of modifications to the PE/COFF
>> header, macroize it and move the definition into a separate source
>> file.
>
> I'm really not keen on portioning out bits of the arm64 header like
> this.
>
> The __jmp macro obscures the first few byes of the header, and we lose
> the obvious relationship between the overlapping portions of the arm64
> and PE/COFF headrs.
>
> I think those portions which have a fixed offset from _head (which is at
> least the overlapping PE/COFF and arm64 header bits) should stay in
> head.S.
>
> Can we factor out only the portions with a dynamic offset from the start
> of the image? i.e. only pe_header and beyond?
>
I have no problem at all with that. It is primarily the PE header, and
not the Image header that clutters up head.S, which is what I am
trying to address with this patch.
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>> arch/arm64/kernel/efi-header.S | 182 ++++++++++++++++++++
>> arch/arm64/kernel/head.S | 171 +-----------------
>> 2 files changed, 186 insertions(+), 167 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
>> new file mode 100644
>> index 000000000000..8c8cd0a8192b
>> --- /dev/null
>> +++ b/arch/arm64/kernel/efi-header.S
>> @@ -0,0 +1,182 @@
>> +/*
>> + * Copyright (C) 2013 - 2017 Linaro, Ltd.
>> + * Copyright (C) 2013, 2014 Red Hat, Inc.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> + .macro __jmp, target
>> +#ifdef CONFIG_EFI
>> + /*
>> + * This add instruction has no meaningful effect except that
>> + * its opcode forms the magic "MZ" signature required by UEFI.
>> + */
>> + add x13, x18, #0x16
>> + b \target
>> +#else
>> + b \target // branch to kernel start, magic
>> + .long 0 // reserved
>> +#endif
>> + .endm
>> +
>> + .macro __EFI_HEADER
>> +#ifdef CONFIG_EFI
>> + .long pe_header - _head // Offset to the PE header.
>> +#else
>> + .word 0 // reserved
>> +#endif
>> +
>> +#ifdef CONFIG_EFI
>> + .align 3
>> +pe_header:
>> + .ascii "PE"
>> + .short 0
>> +coff_header:
>> + .short 0xaa64 // AArch64
>> + .short 2 // nr_sections
>> + .long 0 // TimeDateStamp
>> + .long 0 // PointerToSymbolTable
>> + .long 1 // NumberOfSymbols
>> + .short section_table - optional_header // SizeOfOptionalHeader
>> + .short 0x206 // Characteristics.
>> + // IMAGE_FILE_DEBUG_STRIPPED |
>> + // IMAGE_FILE_EXECUTABLE_IMAGE |
>> + // IMAGE_FILE_LINE_NUMS_STRIPPED
>> +optional_header:
>> + .short 0x20b // PE32+ format
>> + .byte 0x02 // MajorLinkerVersion
>> + .byte 0x14 // MinorLinkerVersion
>> + .long _end - efi_header_end // SizeOfCode
>> + .long 0 // SizeOfInitializedData
>> + .long 0 // SizeOfUninitializedData
>> + .long __efistub_entry - _head // AddressOfEntryPoint
>> + .long efi_header_end - _head // BaseOfCode
>> +
>> +extra_header_fields:
>> + .quad 0 // ImageBase
>> + .long 0x1000 // SectionAlignment
>> + .long PECOFF_FILE_ALIGNMENT // FileAlignment
>> + .short 0 // MajorOperatingSystemVersion
>> + .short 0 // MinorOperatingSystemVersion
>> + .short 0 // MajorImageVersion
>> + .short 0 // MinorImageVersion
>> + .short 0 // MajorSubsystemVersion
>> + .short 0 // MinorSubsystemVersion
>> + .long 0 // Win32VersionValue
>> +
>> + .long _end - _head // SizeOfImage
>> +
>> + // Everything before the kernel image is considered part of the header
>> + .long efi_header_end - _head // SizeOfHeaders
>> + .long 0 // CheckSum
>> + .short 0xa // Subsystem (EFI application)
>> + .short 0 // DllCharacteristics
>> + .quad 0 // SizeOfStackReserve
>> + .quad 0 // SizeOfStackCommit
>> + .quad 0 // SizeOfHeapReserve
>> + .quad 0 // SizeOfHeapCommit
>> + .long 0 // LoaderFlags
>> + .long (section_table - .) / 8 // NumberOfRvaAndSizes
>> +
>> + .quad 0 // ExportTable
>> + .quad 0 // ImportTable
>> + .quad 0 // ResourceTable
>> + .quad 0 // ExceptionTable
>> + .quad 0 // CertificationTable
>> + .quad 0 // BaseRelocationTable
>> +
>> +#ifdef CONFIG_DEBUG_EFI
>> + .long efi_debug_table - _head // DebugTable
>> + .long efi_debug_table_size
>> +#endif
>> +
>> + // Section table
>> +section_table:
>> +
>> + /*
>> + * The EFI application loader requires a relocation section
>> + * because EFI applications must be relocatable. This is a
>> + * dummy section as far as we are concerned.
>> + */
>> + .ascii ".reloc"
>> + .byte 0
>> + .byte 0 // end of 0 padding of section name
>> + .long 0
>> + .long 0
>> + .long 0 // SizeOfRawData
>> + .long 0 // PointerToRawData
>> + .long 0 // PointerToRelocations
>> + .long 0 // PointerToLineNumbers
>> + .short 0 // NumberOfRelocations
>> + .short 0 // NumberOfLineNumbers
>> + .long 0x42100040 // Characteristics (section flags)
>> +
>> +
>> + .ascii ".text"
>> + .byte 0
>> + .byte 0
>> + .byte 0 // end of 0 padding of section name
>> + .long _end - efi_header_end // VirtualSize
>> + .long efi_header_end - _head // VirtualAddress
>> + .long _edata - efi_header_end // SizeOfRawData
>> + .long efi_header_end - _head // PointerToRawData
>> +
>> + .long 0 // PointerToRelocations
>> + .long 0 // PointerToLineNumbers
>> + .short 0 // NumberOfRelocations
>> + .short 0 // NumberOfLineNumbers
>> + .long 0xe0500020 // Characteristics
>> +
>> +#ifdef CONFIG_DEBUG_EFI
>> + /*
>> + * The debug table is referenced via its Relative Virtual Address (RVA),
>> + * which is only defined for those parts of the image that are covered
>> + * by a section declaration. Since this header is not covered by any
>> + * section, the debug table must be emitted elsewhere. So stick it in
>> + * the .init.rodata section instead.
>> + *
>> + * Note that the EFI debug entry itself may legally have a zero RVA,
>> + * which means we can simply put it right after the section headers.
>> + */
>> + __INITRODATA
>> +
>> + .align 2
>> +efi_debug_table:
>> + // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
>> + .long 0 // Characteristics
>> + .long 0 // TimeDateStamp
>> + .short 0 // MajorVersion
>> + .short 0 // MinorVersion
>> + .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
>> + .long efi_debug_entry_size // SizeOfData
>> + .long 0 // RVA
>> + .long efi_debug_entry - _head // FileOffset
>> +
>> + .set efi_debug_table_size, . - efi_debug_table
>> + .previous
>> +
>> +efi_debug_entry:
>> + // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
>> + .ascii "NB10" // Signature
>> + .long 0 // Unknown
>> + .long 0 // Unknown2
>> + .long 0 // Unknown3
>> +
>> + .asciz VMLINUX_PATH
>> +
>> + .set efi_debug_entry_size, . - efi_debug_entry
>> +#endif
>> +
>> + /*
>> + * EFI will load .text onwards at the 4k section alignment
>> + * described in the PE/COFF header. To ensure that instruction
>> + * sequences using an adrp and a :lo12: immediate will function
>> + * correctly at this alignment, we must ensure that .text is
>> + * placed at a 4k boundary in the Image to begin with.
>> + */
>> + .align 12
>> +efi_header_end:
>> +#endif
>> + .endm
>> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
>> index c6cc82ec190b..aca9b184035a 100644
>> --- a/arch/arm64/kernel/head.S
>> +++ b/arch/arm64/kernel/head.S
>> @@ -42,6 +42,8 @@
>> #include <asm/thread_info.h>
>> #include <asm/virt.h>
>>
>> +#include "efi-header.S"
>> +
>> #define __PHYS_OFFSET (KERNEL_START - TEXT_OFFSET)
>>
>> #if (TEXT_OFFSET & 0xfff) != 0
>> @@ -72,17 +74,7 @@ _head:
>> /*
>> * DO NOT MODIFY. Image header expected by Linux boot-loaders.
>> */
>> -#ifdef CONFIG_EFI
>> - /*
>> - * This add instruction has no meaningful effect except that
>> - * its opcode forms the magic "MZ" signature required by UEFI.
>> - */
>> - add x13, x18, #0x16
>> - b stext
>> -#else
>> - b stext // branch to kernel start, magic
>> - .long 0 // reserved
>> -#endif
>> + __jmp stext // Executable code
>> le64sym _kernel_offset_le // Image load offset from start of RAM, little-endian
>> le64sym _kernel_size_le // Effective size of kernel image, little-endian
>> le64sym _kernel_flags_le // Informative flags, little-endian
>> @@ -93,163 +85,8 @@ _head:
>> .byte 0x52
>> .byte 0x4d
>> .byte 0x64
>> -#ifdef CONFIG_EFI
>> - .long pe_header - _head // Offset to the PE header.
>> -#else
>> - .word 0 // reserved
>> -#endif
>> -
>> -#ifdef CONFIG_EFI
>> - .align 3
>> -pe_header:
>> - .ascii "PE"
>> - .short 0
>> -coff_header:
>> - .short 0xaa64 // AArch64
>> - .short 2 // nr_sections
>> - .long 0 // TimeDateStamp
>> - .long 0 // PointerToSymbolTable
>> - .long 1 // NumberOfSymbols
>> - .short section_table - optional_header // SizeOfOptionalHeader
>> - .short 0x206 // Characteristics.
>> - // IMAGE_FILE_DEBUG_STRIPPED |
>> - // IMAGE_FILE_EXECUTABLE_IMAGE |
>> - // IMAGE_FILE_LINE_NUMS_STRIPPED
>> -optional_header:
>> - .short 0x20b // PE32+ format
>> - .byte 0x02 // MajorLinkerVersion
>> - .byte 0x14 // MinorLinkerVersion
>> - .long _end - efi_header_end // SizeOfCode
>> - .long 0 // SizeOfInitializedData
>> - .long 0 // SizeOfUninitializedData
>> - .long __efistub_entry - _head // AddressOfEntryPoint
>> - .long efi_header_end - _head // BaseOfCode
>> -
>> -extra_header_fields:
>> - .quad 0 // ImageBase
>> - .long 0x1000 // SectionAlignment
>> - .long PECOFF_FILE_ALIGNMENT // FileAlignment
>> - .short 0 // MajorOperatingSystemVersion
>> - .short 0 // MinorOperatingSystemVersion
>> - .short 0 // MajorImageVersion
>> - .short 0 // MinorImageVersion
>> - .short 0 // MajorSubsystemVersion
>> - .short 0 // MinorSubsystemVersion
>> - .long 0 // Win32VersionValue
>> -
>> - .long _end - _head // SizeOfImage
>> -
>> - // Everything before the kernel image is considered part of the header
>> - .long efi_header_end - _head // SizeOfHeaders
>> - .long 0 // CheckSum
>> - .short 0xa // Subsystem (EFI application)
>> - .short 0 // DllCharacteristics
>> - .quad 0 // SizeOfStackReserve
>> - .quad 0 // SizeOfStackCommit
>> - .quad 0 // SizeOfHeapReserve
>> - .quad 0 // SizeOfHeapCommit
>> - .long 0 // LoaderFlags
>> - .long (section_table - .) / 8 // NumberOfRvaAndSizes
>> -
>> - .quad 0 // ExportTable
>> - .quad 0 // ImportTable
>> - .quad 0 // ResourceTable
>> - .quad 0 // ExceptionTable
>> - .quad 0 // CertificationTable
>> - .quad 0 // BaseRelocationTable
>> -
>> -#ifdef CONFIG_DEBUG_EFI
>> - .long efi_debug_table - _head // DebugTable
>> - .long efi_debug_table_size
>> -#endif
>> -
>> - // Section table
>> -section_table:
>>
>> - /*
>> - * The EFI application loader requires a relocation section
>> - * because EFI applications must be relocatable. This is a
>> - * dummy section as far as we are concerned.
>> - */
>> - .ascii ".reloc"
>> - .byte 0
>> - .byte 0 // end of 0 padding of section name
>> - .long 0
>> - .long 0
>> - .long 0 // SizeOfRawData
>> - .long 0 // PointerToRawData
>> - .long 0 // PointerToRelocations
>> - .long 0 // PointerToLineNumbers
>> - .short 0 // NumberOfRelocations
>> - .short 0 // NumberOfLineNumbers
>> - .long 0x42100040 // Characteristics (section flags)
>> -
>> -
>> - .ascii ".text"
>> - .byte 0
>> - .byte 0
>> - .byte 0 // end of 0 padding of section name
>> - .long _end - efi_header_end // VirtualSize
>> - .long efi_header_end - _head // VirtualAddress
>> - .long _edata - efi_header_end // SizeOfRawData
>> - .long efi_header_end - _head // PointerToRawData
>> -
>> - .long 0 // PointerToRelocations (0 for executables)
>> - .long 0 // PointerToLineNumbers (0 for executables)
>> - .short 0 // NumberOfRelocations (0 for executables)
>> - .short 0 // NumberOfLineNumbers (0 for executables)
>> - .long 0xe0500020 // Characteristics (section flags)
>> -
>> -#ifdef CONFIG_DEBUG_EFI
>> - /*
>> - * The debug table is referenced via its Relative Virtual Address (RVA),
>> - * which is only defined for those parts of the image that are covered
>> - * by a section declaration. Since this header is not covered by any
>> - * section, the debug table must be emitted elsewhere. So stick it in
>> - * the .init.rodata section instead.
>> - *
>> - * Note that the EFI debug entry itself may legally have a zero RVA,
>> - * which means we can simply put it right after the section headers.
>> - */
>> - __INITRODATA
>> -
>> - .align 2
>> -efi_debug_table:
>> - // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
>> - .long 0 // Characteristics
>> - .long 0 // TimeDateStamp
>> - .short 0 // MajorVersion
>> - .short 0 // MinorVersion
>> - .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
>> - .long efi_debug_entry_size // SizeOfData
>> - .long 0 // RVA
>> - .long efi_debug_entry - _head // FileOffset
>> -
>> - .set efi_debug_table_size, . - efi_debug_table
>> - .previous
>> -
>> -efi_debug_entry:
>> - // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
>> - .ascii "NB10" // Signature
>> - .long 0 // Unknown
>> - .long 0 // Unknown2
>> - .long 0 // Unknown3
>> -
>> - .asciz VMLINUX_PATH
>> -
>> - .set efi_debug_entry_size, . - efi_debug_entry
>> -#endif
>> -
>> - /*
>> - * EFI will load .text onwards at the 4k section alignment
>> - * described in the PE/COFF header. To ensure that instruction
>> - * sequences using an adrp and a :lo12: immediate will function
>> - * correctly at this alignment, we must ensure that .text is
>> - * placed at a 4k boundary in the Image to begin with.
>> - */
>> - .align 12
>> -efi_header_end:
>> -#endif
>> + __EFI_HEADER
>>
>> __INIT
>>
>> --
>> 2.7.4
>>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [kernel-hardening] Re: [PATCH 3/7] arm64: efi: move EFI header and related data to a separate .S file
@ 2017-02-06 17:07 ` Ard Biesheuvel
0 siblings, 0 replies; 32+ messages in thread
From: Ard Biesheuvel @ 2017-02-06 17:07 UTC (permalink / raw)
To: Mark Rutland
Cc: linux-arm-kernel, Will Deacon, Catalin Marinas, Laura Abbott,
kernel-hardening, Leif Lindholm, Peter Jones
On 6 February 2017 at 17:03, Mark Rutland <mark.rutland@arm.com> wrote:
> On Mon, Feb 06, 2017 at 04:24:31PM +0000, Ard Biesheuvel wrote:
>> In preparation of yet another round of modifications to the PE/COFF
>> header, macroize it and move the definition into a separate source
>> file.
>
> I'm really not keen on portioning out bits of the arm64 header like
> this.
>
> The __jmp macro obscures the first few byes of the header, and we lose
> the obvious relationship between the overlapping portions of the arm64
> and PE/COFF headrs.
>
> I think those portions which have a fixed offset from _head (which is at
> least the overlapping PE/COFF and arm64 header bits) should stay in
> head.S.
>
> Can we factor out only the portions with a dynamic offset from the start
> of the image? i.e. only pe_header and beyond?
>
I have no problem at all with that. It is primarily the PE header, and
not the Image header that clutters up head.S, which is what I am
trying to address with this patch.
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>> arch/arm64/kernel/efi-header.S | 182 ++++++++++++++++++++
>> arch/arm64/kernel/head.S | 171 +-----------------
>> 2 files changed, 186 insertions(+), 167 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
>> new file mode 100644
>> index 000000000000..8c8cd0a8192b
>> --- /dev/null
>> +++ b/arch/arm64/kernel/efi-header.S
>> @@ -0,0 +1,182 @@
>> +/*
>> + * Copyright (C) 2013 - 2017 Linaro, Ltd.
>> + * Copyright (C) 2013, 2014 Red Hat, Inc.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> + .macro __jmp, target
>> +#ifdef CONFIG_EFI
>> + /*
>> + * This add instruction has no meaningful effect except that
>> + * its opcode forms the magic "MZ" signature required by UEFI.
>> + */
>> + add x13, x18, #0x16
>> + b \target
>> +#else
>> + b \target // branch to kernel start, magic
>> + .long 0 // reserved
>> +#endif
>> + .endm
>> +
>> + .macro __EFI_HEADER
>> +#ifdef CONFIG_EFI
>> + .long pe_header - _head // Offset to the PE header.
>> +#else
>> + .word 0 // reserved
>> +#endif
>> +
>> +#ifdef CONFIG_EFI
>> + .align 3
>> +pe_header:
>> + .ascii "PE"
>> + .short 0
>> +coff_header:
>> + .short 0xaa64 // AArch64
>> + .short 2 // nr_sections
>> + .long 0 // TimeDateStamp
>> + .long 0 // PointerToSymbolTable
>> + .long 1 // NumberOfSymbols
>> + .short section_table - optional_header // SizeOfOptionalHeader
>> + .short 0x206 // Characteristics.
>> + // IMAGE_FILE_DEBUG_STRIPPED |
>> + // IMAGE_FILE_EXECUTABLE_IMAGE |
>> + // IMAGE_FILE_LINE_NUMS_STRIPPED
>> +optional_header:
>> + .short 0x20b // PE32+ format
>> + .byte 0x02 // MajorLinkerVersion
>> + .byte 0x14 // MinorLinkerVersion
>> + .long _end - efi_header_end // SizeOfCode
>> + .long 0 // SizeOfInitializedData
>> + .long 0 // SizeOfUninitializedData
>> + .long __efistub_entry - _head // AddressOfEntryPoint
>> + .long efi_header_end - _head // BaseOfCode
>> +
>> +extra_header_fields:
>> + .quad 0 // ImageBase
>> + .long 0x1000 // SectionAlignment
>> + .long PECOFF_FILE_ALIGNMENT // FileAlignment
>> + .short 0 // MajorOperatingSystemVersion
>> + .short 0 // MinorOperatingSystemVersion
>> + .short 0 // MajorImageVersion
>> + .short 0 // MinorImageVersion
>> + .short 0 // MajorSubsystemVersion
>> + .short 0 // MinorSubsystemVersion
>> + .long 0 // Win32VersionValue
>> +
>> + .long _end - _head // SizeOfImage
>> +
>> + // Everything before the kernel image is considered part of the header
>> + .long efi_header_end - _head // SizeOfHeaders
>> + .long 0 // CheckSum
>> + .short 0xa // Subsystem (EFI application)
>> + .short 0 // DllCharacteristics
>> + .quad 0 // SizeOfStackReserve
>> + .quad 0 // SizeOfStackCommit
>> + .quad 0 // SizeOfHeapReserve
>> + .quad 0 // SizeOfHeapCommit
>> + .long 0 // LoaderFlags
>> + .long (section_table - .) / 8 // NumberOfRvaAndSizes
>> +
>> + .quad 0 // ExportTable
>> + .quad 0 // ImportTable
>> + .quad 0 // ResourceTable
>> + .quad 0 // ExceptionTable
>> + .quad 0 // CertificationTable
>> + .quad 0 // BaseRelocationTable
>> +
>> +#ifdef CONFIG_DEBUG_EFI
>> + .long efi_debug_table - _head // DebugTable
>> + .long efi_debug_table_size
>> +#endif
>> +
>> + // Section table
>> +section_table:
>> +
>> + /*
>> + * The EFI application loader requires a relocation section
>> + * because EFI applications must be relocatable. This is a
>> + * dummy section as far as we are concerned.
>> + */
>> + .ascii ".reloc"
>> + .byte 0
>> + .byte 0 // end of 0 padding of section name
>> + .long 0
>> + .long 0
>> + .long 0 // SizeOfRawData
>> + .long 0 // PointerToRawData
>> + .long 0 // PointerToRelocations
>> + .long 0 // PointerToLineNumbers
>> + .short 0 // NumberOfRelocations
>> + .short 0 // NumberOfLineNumbers
>> + .long 0x42100040 // Characteristics (section flags)
>> +
>> +
>> + .ascii ".text"
>> + .byte 0
>> + .byte 0
>> + .byte 0 // end of 0 padding of section name
>> + .long _end - efi_header_end // VirtualSize
>> + .long efi_header_end - _head // VirtualAddress
>> + .long _edata - efi_header_end // SizeOfRawData
>> + .long efi_header_end - _head // PointerToRawData
>> +
>> + .long 0 // PointerToRelocations
>> + .long 0 // PointerToLineNumbers
>> + .short 0 // NumberOfRelocations
>> + .short 0 // NumberOfLineNumbers
>> + .long 0xe0500020 // Characteristics
>> +
>> +#ifdef CONFIG_DEBUG_EFI
>> + /*
>> + * The debug table is referenced via its Relative Virtual Address (RVA),
>> + * which is only defined for those parts of the image that are covered
>> + * by a section declaration. Since this header is not covered by any
>> + * section, the debug table must be emitted elsewhere. So stick it in
>> + * the .init.rodata section instead.
>> + *
>> + * Note that the EFI debug entry itself may legally have a zero RVA,
>> + * which means we can simply put it right after the section headers.
>> + */
>> + __INITRODATA
>> +
>> + .align 2
>> +efi_debug_table:
>> + // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
>> + .long 0 // Characteristics
>> + .long 0 // TimeDateStamp
>> + .short 0 // MajorVersion
>> + .short 0 // MinorVersion
>> + .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
>> + .long efi_debug_entry_size // SizeOfData
>> + .long 0 // RVA
>> + .long efi_debug_entry - _head // FileOffset
>> +
>> + .set efi_debug_table_size, . - efi_debug_table
>> + .previous
>> +
>> +efi_debug_entry:
>> + // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
>> + .ascii "NB10" // Signature
>> + .long 0 // Unknown
>> + .long 0 // Unknown2
>> + .long 0 // Unknown3
>> +
>> + .asciz VMLINUX_PATH
>> +
>> + .set efi_debug_entry_size, . - efi_debug_entry
>> +#endif
>> +
>> + /*
>> + * EFI will load .text onwards at the 4k section alignment
>> + * described in the PE/COFF header. To ensure that instruction
>> + * sequences using an adrp and a :lo12: immediate will function
>> + * correctly at this alignment, we must ensure that .text is
>> + * placed at a 4k boundary in the Image to begin with.
>> + */
>> + .align 12
>> +efi_header_end:
>> +#endif
>> + .endm
>> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
>> index c6cc82ec190b..aca9b184035a 100644
>> --- a/arch/arm64/kernel/head.S
>> +++ b/arch/arm64/kernel/head.S
>> @@ -42,6 +42,8 @@
>> #include <asm/thread_info.h>
>> #include <asm/virt.h>
>>
>> +#include "efi-header.S"
>> +
>> #define __PHYS_OFFSET (KERNEL_START - TEXT_OFFSET)
>>
>> #if (TEXT_OFFSET & 0xfff) != 0
>> @@ -72,17 +74,7 @@ _head:
>> /*
>> * DO NOT MODIFY. Image header expected by Linux boot-loaders.
>> */
>> -#ifdef CONFIG_EFI
>> - /*
>> - * This add instruction has no meaningful effect except that
>> - * its opcode forms the magic "MZ" signature required by UEFI.
>> - */
>> - add x13, x18, #0x16
>> - b stext
>> -#else
>> - b stext // branch to kernel start, magic
>> - .long 0 // reserved
>> -#endif
>> + __jmp stext // Executable code
>> le64sym _kernel_offset_le // Image load offset from start of RAM, little-endian
>> le64sym _kernel_size_le // Effective size of kernel image, little-endian
>> le64sym _kernel_flags_le // Informative flags, little-endian
>> @@ -93,163 +85,8 @@ _head:
>> .byte 0x52
>> .byte 0x4d
>> .byte 0x64
>> -#ifdef CONFIG_EFI
>> - .long pe_header - _head // Offset to the PE header.
>> -#else
>> - .word 0 // reserved
>> -#endif
>> -
>> -#ifdef CONFIG_EFI
>> - .align 3
>> -pe_header:
>> - .ascii "PE"
>> - .short 0
>> -coff_header:
>> - .short 0xaa64 // AArch64
>> - .short 2 // nr_sections
>> - .long 0 // TimeDateStamp
>> - .long 0 // PointerToSymbolTable
>> - .long 1 // NumberOfSymbols
>> - .short section_table - optional_header // SizeOfOptionalHeader
>> - .short 0x206 // Characteristics.
>> - // IMAGE_FILE_DEBUG_STRIPPED |
>> - // IMAGE_FILE_EXECUTABLE_IMAGE |
>> - // IMAGE_FILE_LINE_NUMS_STRIPPED
>> -optional_header:
>> - .short 0x20b // PE32+ format
>> - .byte 0x02 // MajorLinkerVersion
>> - .byte 0x14 // MinorLinkerVersion
>> - .long _end - efi_header_end // SizeOfCode
>> - .long 0 // SizeOfInitializedData
>> - .long 0 // SizeOfUninitializedData
>> - .long __efistub_entry - _head // AddressOfEntryPoint
>> - .long efi_header_end - _head // BaseOfCode
>> -
>> -extra_header_fields:
>> - .quad 0 // ImageBase
>> - .long 0x1000 // SectionAlignment
>> - .long PECOFF_FILE_ALIGNMENT // FileAlignment
>> - .short 0 // MajorOperatingSystemVersion
>> - .short 0 // MinorOperatingSystemVersion
>> - .short 0 // MajorImageVersion
>> - .short 0 // MinorImageVersion
>> - .short 0 // MajorSubsystemVersion
>> - .short 0 // MinorSubsystemVersion
>> - .long 0 // Win32VersionValue
>> -
>> - .long _end - _head // SizeOfImage
>> -
>> - // Everything before the kernel image is considered part of the header
>> - .long efi_header_end - _head // SizeOfHeaders
>> - .long 0 // CheckSum
>> - .short 0xa // Subsystem (EFI application)
>> - .short 0 // DllCharacteristics
>> - .quad 0 // SizeOfStackReserve
>> - .quad 0 // SizeOfStackCommit
>> - .quad 0 // SizeOfHeapReserve
>> - .quad 0 // SizeOfHeapCommit
>> - .long 0 // LoaderFlags
>> - .long (section_table - .) / 8 // NumberOfRvaAndSizes
>> -
>> - .quad 0 // ExportTable
>> - .quad 0 // ImportTable
>> - .quad 0 // ResourceTable
>> - .quad 0 // ExceptionTable
>> - .quad 0 // CertificationTable
>> - .quad 0 // BaseRelocationTable
>> -
>> -#ifdef CONFIG_DEBUG_EFI
>> - .long efi_debug_table - _head // DebugTable
>> - .long efi_debug_table_size
>> -#endif
>> -
>> - // Section table
>> -section_table:
>>
>> - /*
>> - * The EFI application loader requires a relocation section
>> - * because EFI applications must be relocatable. This is a
>> - * dummy section as far as we are concerned.
>> - */
>> - .ascii ".reloc"
>> - .byte 0
>> - .byte 0 // end of 0 padding of section name
>> - .long 0
>> - .long 0
>> - .long 0 // SizeOfRawData
>> - .long 0 // PointerToRawData
>> - .long 0 // PointerToRelocations
>> - .long 0 // PointerToLineNumbers
>> - .short 0 // NumberOfRelocations
>> - .short 0 // NumberOfLineNumbers
>> - .long 0x42100040 // Characteristics (section flags)
>> -
>> -
>> - .ascii ".text"
>> - .byte 0
>> - .byte 0
>> - .byte 0 // end of 0 padding of section name
>> - .long _end - efi_header_end // VirtualSize
>> - .long efi_header_end - _head // VirtualAddress
>> - .long _edata - efi_header_end // SizeOfRawData
>> - .long efi_header_end - _head // PointerToRawData
>> -
>> - .long 0 // PointerToRelocations (0 for executables)
>> - .long 0 // PointerToLineNumbers (0 for executables)
>> - .short 0 // NumberOfRelocations (0 for executables)
>> - .short 0 // NumberOfLineNumbers (0 for executables)
>> - .long 0xe0500020 // Characteristics (section flags)
>> -
>> -#ifdef CONFIG_DEBUG_EFI
>> - /*
>> - * The debug table is referenced via its Relative Virtual Address (RVA),
>> - * which is only defined for those parts of the image that are covered
>> - * by a section declaration. Since this header is not covered by any
>> - * section, the debug table must be emitted elsewhere. So stick it in
>> - * the .init.rodata section instead.
>> - *
>> - * Note that the EFI debug entry itself may legally have a zero RVA,
>> - * which means we can simply put it right after the section headers.
>> - */
>> - __INITRODATA
>> -
>> - .align 2
>> -efi_debug_table:
>> - // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
>> - .long 0 // Characteristics
>> - .long 0 // TimeDateStamp
>> - .short 0 // MajorVersion
>> - .short 0 // MinorVersion
>> - .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
>> - .long efi_debug_entry_size // SizeOfData
>> - .long 0 // RVA
>> - .long efi_debug_entry - _head // FileOffset
>> -
>> - .set efi_debug_table_size, . - efi_debug_table
>> - .previous
>> -
>> -efi_debug_entry:
>> - // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
>> - .ascii "NB10" // Signature
>> - .long 0 // Unknown
>> - .long 0 // Unknown2
>> - .long 0 // Unknown3
>> -
>> - .asciz VMLINUX_PATH
>> -
>> - .set efi_debug_entry_size, . - efi_debug_entry
>> -#endif
>> -
>> - /*
>> - * EFI will load .text onwards at the 4k section alignment
>> - * described in the PE/COFF header. To ensure that instruction
>> - * sequences using an adrp and a :lo12: immediate will function
>> - * correctly at this alignment, we must ensure that .text is
>> - * placed at a 4k boundary in the Image to begin with.
>> - */
>> - .align 12
>> -efi_header_end:
>> -#endif
>> + __EFI_HEADER
>>
>> __INIT
>>
>> --
>> 2.7.4
>>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 6/7] arm64: efi: replace open coded constants with symbolic ones
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-06 17:13 ` Mark Rutland
-1 siblings, 0 replies; 32+ messages in thread
From: Mark Rutland @ 2017-02-06 17:13 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 06, 2017 at 04:24:34PM +0000, Ard Biesheuvel wrote:
> Replace open coded constants with symbolic ones throughout the
> Image and the EFI headers. Note that in two cases, this removes
> a value that the PE/COFF spec does not allow:
> - NumberOfSymbols in the PE header should be 0
> - PE/COFF executable sections (as opposed to sections in object files)
> should not use the section alignment flags
I take it that EDK2 doesn't care about either of these, but perhaps we
should fix those in a preparatory patch, at the start of the series, to
separate fixes from rework.
That also makes it easier to binary-diff an Image after this patch, to
ensure that the mnemonicisation is correct. ;)
Otherwise, this generally looks fine.
Thanks,
Mark.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> arch/arm64/kernel/efi-header.S | 37 ++++++++++----------
> arch/arm64/kernel/head.S | 5 +--
> 2 files changed, 20 insertions(+), 22 deletions(-)
>
> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
> index 35b11654ecc5..c87c23336c86 100644
> --- a/arch/arm64/kernel/efi-header.S
> +++ b/arch/arm64/kernel/efi-header.S
> @@ -7,6 +7,8 @@
> * published by the Free Software Foundation.
> */
>
> +#include <linux/pe.h>
> +
> .macro __jmp, target
> #ifdef CONFIG_EFI
> /*
> @@ -33,21 +35,20 @@
> .long pe_header - _head // Offset to the PE header.
>
> pe_header:
> - .ascii "PE"
> - .short 0
> + .long PE_MAGIC
> coff_header:
> - .short 0xaa64 // AArch64
> - .short 1 // nr_sections
> + .short IMAGE_FILE_MACHINE_ARM64 // Machine
> + .short 1 // NumberOfSections
> .long 0 // TimeDateStamp
> .long 0 // PointerToSymbolTable
> - .long 1 // NumberOfSymbols
> + .long 0 // NumberOfSymbols
> .short section_table - optional_header // SizeOfOptionalHeader
> - .short 0x206 // Characteristics.
> - // IMAGE_FILE_DEBUG_STRIPPED |
> - // IMAGE_FILE_EXECUTABLE_IMAGE |
> - // IMAGE_FILE_LINE_NUMS_STRIPPED
> + .short IMAGE_FILE_DEBUG_STRIPPED | \
> + IMAGE_FILE_EXECUTABLE_IMAGE | \
> + IMAGE_FILE_LINE_NUMS_STRIPPED // Characteristics
> +
> optional_header:
> - .short 0x20b // PE32+ format
> + .short PE_OPT_MAGIC_PE32PLUS // PE32+ format
> .byte 0x02 // MajorLinkerVersion
> .byte 0x14 // MinorLinkerVersion
> .long _end - efi_header_end // SizeOfCode
> @@ -58,7 +59,7 @@ optional_header:
>
> extra_header_fields:
> .quad 0 // ImageBase
> - .long 0x1000 // SectionAlignment
> + .long SZ_4K // SectionAlignment
> .long PECOFF_FILE_ALIGNMENT // FileAlignment
> .short 0 // MajorOperatingSystemVersion
> .short 0 // MinorOperatingSystemVersion
> @@ -73,7 +74,7 @@ extra_header_fields:
> // Everything before the kernel image is considered part of the header
> .long efi_header_end - _head // SizeOfHeaders
> .long 0 // CheckSum
> - .short 0xa // Subsystem (EFI application)
> + .short IMAGE_SUBSYSTEM_EFI_APPLICATION // Subsystem
> .short 0 // DllCharacteristics
> .quad 0 // SizeOfStackReserve
> .quad 0 // SizeOfStackCommit
> @@ -96,10 +97,7 @@ extra_header_fields:
>
> // Section table
> section_table:
> - .ascii ".text"
> - .byte 0
> - .byte 0
> - .byte 0 // end of 0 padding of section name
> + .ascii ".text\0\0\0"
> .long _end - efi_header_end // VirtualSize
> .long efi_header_end - _head // VirtualAddress
> .long _edata - efi_header_end // SizeOfRawData
> @@ -109,7 +107,10 @@ section_table:
> .long 0 // PointerToLineNumbers
> .short 0 // NumberOfRelocations
> .short 0 // NumberOfLineNumbers
> - .long 0xe0500020 // Characteristics
> + .long IMAGE_SCN_CNT_CODE | \
> + IMAGE_SCN_MEM_EXECUTE | \
> + IMAGE_SCN_MEM_READ | \
> + IMAGE_SCN_MEM_WRITE // Characteristics
>
> #ifdef CONFIG_DEBUG_EFI
> /*
> @@ -131,7 +132,7 @@ efi_debug_table:
> .long 0 // TimeDateStamp
> .short 0 // MajorVersion
> .short 0 // MinorVersion
> - .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
> + .long IMAGE_DEBUG_TYPE_CODEVIEW // Type
> .long efi_debug_entry_size // SizeOfData
> .long 0 // RVA
> .long efi_debug_entry - _head // FileOffset
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index aca9b184035a..055735ba3600 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -81,10 +81,7 @@ _head:
> .quad 0 // reserved
> .quad 0 // reserved
> .quad 0 // reserved
> - .byte 0x41 // Magic number, "ARM\x64"
> - .byte 0x52
> - .byte 0x4d
> - .byte 0x64
> + .ascii "ARM\x64" // Magic number
>
> __EFI_HEADER
>
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [kernel-hardening] Re: [PATCH 6/7] arm64: efi: replace open coded constants with symbolic ones
@ 2017-02-06 17:13 ` Mark Rutland
0 siblings, 0 replies; 32+ messages in thread
From: Mark Rutland @ 2017-02-06 17:13 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-arm-kernel, will.deacon, catalin.marinas, labbott,
kernel-hardening, leif.lindholm, pjones
On Mon, Feb 06, 2017 at 04:24:34PM +0000, Ard Biesheuvel wrote:
> Replace open coded constants with symbolic ones throughout the
> Image and the EFI headers. Note that in two cases, this removes
> a value that the PE/COFF spec does not allow:
> - NumberOfSymbols in the PE header should be 0
> - PE/COFF executable sections (as opposed to sections in object files)
> should not use the section alignment flags
I take it that EDK2 doesn't care about either of these, but perhaps we
should fix those in a preparatory patch, at the start of the series, to
separate fixes from rework.
That also makes it easier to binary-diff an Image after this patch, to
ensure that the mnemonicisation is correct. ;)
Otherwise, this generally looks fine.
Thanks,
Mark.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> arch/arm64/kernel/efi-header.S | 37 ++++++++++----------
> arch/arm64/kernel/head.S | 5 +--
> 2 files changed, 20 insertions(+), 22 deletions(-)
>
> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
> index 35b11654ecc5..c87c23336c86 100644
> --- a/arch/arm64/kernel/efi-header.S
> +++ b/arch/arm64/kernel/efi-header.S
> @@ -7,6 +7,8 @@
> * published by the Free Software Foundation.
> */
>
> +#include <linux/pe.h>
> +
> .macro __jmp, target
> #ifdef CONFIG_EFI
> /*
> @@ -33,21 +35,20 @@
> .long pe_header - _head // Offset to the PE header.
>
> pe_header:
> - .ascii "PE"
> - .short 0
> + .long PE_MAGIC
> coff_header:
> - .short 0xaa64 // AArch64
> - .short 1 // nr_sections
> + .short IMAGE_FILE_MACHINE_ARM64 // Machine
> + .short 1 // NumberOfSections
> .long 0 // TimeDateStamp
> .long 0 // PointerToSymbolTable
> - .long 1 // NumberOfSymbols
> + .long 0 // NumberOfSymbols
> .short section_table - optional_header // SizeOfOptionalHeader
> - .short 0x206 // Characteristics.
> - // IMAGE_FILE_DEBUG_STRIPPED |
> - // IMAGE_FILE_EXECUTABLE_IMAGE |
> - // IMAGE_FILE_LINE_NUMS_STRIPPED
> + .short IMAGE_FILE_DEBUG_STRIPPED | \
> + IMAGE_FILE_EXECUTABLE_IMAGE | \
> + IMAGE_FILE_LINE_NUMS_STRIPPED // Characteristics
> +
> optional_header:
> - .short 0x20b // PE32+ format
> + .short PE_OPT_MAGIC_PE32PLUS // PE32+ format
> .byte 0x02 // MajorLinkerVersion
> .byte 0x14 // MinorLinkerVersion
> .long _end - efi_header_end // SizeOfCode
> @@ -58,7 +59,7 @@ optional_header:
>
> extra_header_fields:
> .quad 0 // ImageBase
> - .long 0x1000 // SectionAlignment
> + .long SZ_4K // SectionAlignment
> .long PECOFF_FILE_ALIGNMENT // FileAlignment
> .short 0 // MajorOperatingSystemVersion
> .short 0 // MinorOperatingSystemVersion
> @@ -73,7 +74,7 @@ extra_header_fields:
> // Everything before the kernel image is considered part of the header
> .long efi_header_end - _head // SizeOfHeaders
> .long 0 // CheckSum
> - .short 0xa // Subsystem (EFI application)
> + .short IMAGE_SUBSYSTEM_EFI_APPLICATION // Subsystem
> .short 0 // DllCharacteristics
> .quad 0 // SizeOfStackReserve
> .quad 0 // SizeOfStackCommit
> @@ -96,10 +97,7 @@ extra_header_fields:
>
> // Section table
> section_table:
> - .ascii ".text"
> - .byte 0
> - .byte 0
> - .byte 0 // end of 0 padding of section name
> + .ascii ".text\0\0\0"
> .long _end - efi_header_end // VirtualSize
> .long efi_header_end - _head // VirtualAddress
> .long _edata - efi_header_end // SizeOfRawData
> @@ -109,7 +107,10 @@ section_table:
> .long 0 // PointerToLineNumbers
> .short 0 // NumberOfRelocations
> .short 0 // NumberOfLineNumbers
> - .long 0xe0500020 // Characteristics
> + .long IMAGE_SCN_CNT_CODE | \
> + IMAGE_SCN_MEM_EXECUTE | \
> + IMAGE_SCN_MEM_READ | \
> + IMAGE_SCN_MEM_WRITE // Characteristics
>
> #ifdef CONFIG_DEBUG_EFI
> /*
> @@ -131,7 +132,7 @@ efi_debug_table:
> .long 0 // TimeDateStamp
> .short 0 // MajorVersion
> .short 0 // MinorVersion
> - .long 2 // Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW
> + .long IMAGE_DEBUG_TYPE_CODEVIEW // Type
> .long efi_debug_entry_size // SizeOfData
> .long 0 // RVA
> .long efi_debug_entry - _head // FileOffset
> diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
> index aca9b184035a..055735ba3600 100644
> --- a/arch/arm64/kernel/head.S
> +++ b/arch/arm64/kernel/head.S
> @@ -81,10 +81,7 @@ _head:
> .quad 0 // reserved
> .quad 0 // reserved
> .quad 0 // reserved
> - .byte 0x41 // Magic number, "ARM\x64"
> - .byte 0x52
> - .byte 0x4d
> - .byte 0x64
> + .ascii "ARM\x64" // Magic number
>
> __EFI_HEADER
>
> --
> 2.7.4
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 5/7] arm64: efi: remove pointless dummy .reloc section
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
@ 2017-02-07 18:30 ` Peter Jones
-1 siblings, 0 replies; 32+ messages in thread
From: Peter Jones @ 2017-02-07 18:30 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Feb 06, 2017 at 04:24:33PM +0000, Ard Biesheuvel wrote:
> The kernel's EFI PE/COFF header contains a dummy .reloc section, and
> an explanatory comment that claims that this is required for the EFI
> application loader to accept the Image as a relocatable image (i.e.,
> one that can be loaded at any offset and fixed up in place)
>
> This was inherited from the x86 implementation, which has elaborate host
> tooling to mangle the PE/COFF header post-link time, and which populates
> the .reloc section with a single dummy base relocation. On ARM, no such
> tooling exists, and the .reloc section remains empty, and is never even
> exposed via the BaseRelocationTable directory entry, which is where the
> PE/COFF loader looks for it.
>
> The PE/COFF spec is unclear about relocatable images that do not require
> any fixups, but the EDK2 implementation, which is the de facto reference
> for PE/COFF in the UEFI space, clearly does not care, and explicitly
> mentions (in a comment) that relocatable images with no base relocations
> are perfectly fine, as long as they don't have the RELOCS_STRIPPED
> attribute set (which is not the case for our PE/COFF image)
>
> So simply remove the .reloc section altogether.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Looks completely reasonable to me.
Acked-by: Peter Jones <pjones@redhat.com>
> ---
> arch/arm64/kernel/efi-header.S | 22 +-------------------
> 1 file changed, 1 insertion(+), 21 deletions(-)
>
> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
> index 74a25c09a1b8..35b11654ecc5 100644
> --- a/arch/arm64/kernel/efi-header.S
> +++ b/arch/arm64/kernel/efi-header.S
> @@ -37,7 +37,7 @@ pe_header:
> .short 0
> coff_header:
> .short 0xaa64 // AArch64
> - .short 2 // nr_sections
> + .short 1 // nr_sections
> .long 0 // TimeDateStamp
> .long 0 // PointerToSymbolTable
> .long 1 // NumberOfSymbols
> @@ -96,26 +96,6 @@ extra_header_fields:
>
> // Section table
> section_table:
> -
> - /*
> - * The EFI application loader requires a relocation section
> - * because EFI applications must be relocatable. This is a
> - * dummy section as far as we are concerned.
> - */
> - .ascii ".reloc"
> - .byte 0
> - .byte 0 // end of 0 padding of section name
> - .long 0
> - .long 0
> - .long 0 // SizeOfRawData
> - .long 0 // PointerToRawData
> - .long 0 // PointerToRelocations
> - .long 0 // PointerToLineNumbers
> - .short 0 // NumberOfRelocations
> - .short 0 // NumberOfLineNumbers
> - .long 0x42100040 // Characteristics (section flags)
> -
> -
> .ascii ".text"
> .byte 0
> .byte 0
> --
> 2.7.4
>
--
Peter
^ permalink raw reply [flat|nested] 32+ messages in thread
* [kernel-hardening] Re: [PATCH 5/7] arm64: efi: remove pointless dummy .reloc section
@ 2017-02-07 18:30 ` Peter Jones
0 siblings, 0 replies; 32+ messages in thread
From: Peter Jones @ 2017-02-07 18:30 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: linux-arm-kernel, will.deacon, catalin.marinas, mark.rutland,
labbott, kernel-hardening, leif.lindholm
On Mon, Feb 06, 2017 at 04:24:33PM +0000, Ard Biesheuvel wrote:
> The kernel's EFI PE/COFF header contains a dummy .reloc section, and
> an explanatory comment that claims that this is required for the EFI
> application loader to accept the Image as a relocatable image (i.e.,
> one that can be loaded at any offset and fixed up in place)
>
> This was inherited from the x86 implementation, which has elaborate host
> tooling to mangle the PE/COFF header post-link time, and which populates
> the .reloc section with a single dummy base relocation. On ARM, no such
> tooling exists, and the .reloc section remains empty, and is never even
> exposed via the BaseRelocationTable directory entry, which is where the
> PE/COFF loader looks for it.
>
> The PE/COFF spec is unclear about relocatable images that do not require
> any fixups, but the EDK2 implementation, which is the de facto reference
> for PE/COFF in the UEFI space, clearly does not care, and explicitly
> mentions (in a comment) that relocatable images with no base relocations
> are perfectly fine, as long as they don't have the RELOCS_STRIPPED
> attribute set (which is not the case for our PE/COFF image)
>
> So simply remove the .reloc section altogether.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Looks completely reasonable to me.
Acked-by: Peter Jones <pjones@redhat.com>
> ---
> arch/arm64/kernel/efi-header.S | 22 +-------------------
> 1 file changed, 1 insertion(+), 21 deletions(-)
>
> diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S
> index 74a25c09a1b8..35b11654ecc5 100644
> --- a/arch/arm64/kernel/efi-header.S
> +++ b/arch/arm64/kernel/efi-header.S
> @@ -37,7 +37,7 @@ pe_header:
> .short 0
> coff_header:
> .short 0xaa64 // AArch64
> - .short 2 // nr_sections
> + .short 1 // nr_sections
> .long 0 // TimeDateStamp
> .long 0 // PointerToSymbolTable
> .long 1 // NumberOfSymbols
> @@ -96,26 +96,6 @@ extra_header_fields:
>
> // Section table
> section_table:
> -
> - /*
> - * The EFI application loader requires a relocation section
> - * because EFI applications must be relocatable. This is a
> - * dummy section as far as we are concerned.
> - */
> - .ascii ".reloc"
> - .byte 0
> - .byte 0 // end of 0 padding of section name
> - .long 0
> - .long 0
> - .long 0 // SizeOfRawData
> - .long 0 // PointerToRawData
> - .long 0 // PointerToRelocations
> - .long 0 // PointerToLineNumbers
> - .short 0 // NumberOfRelocations
> - .short 0 // NumberOfLineNumbers
> - .long 0x42100040 // Characteristics (section flags)
> -
> -
> .ascii ".text"
> .byte 0
> .byte 0
> --
> 2.7.4
>
--
Peter
^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2017-02-07 18:30 UTC | newest]
Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-06 16:24 [PATCH 0/7] arm64: efi: PE/COFF cleanup/hardening Ard Biesheuvel
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
2017-02-06 16:24 ` [PATCH 1/7] include: pe.h: allow for use in assembly Ard Biesheuvel
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
2017-02-06 16:33 ` Mark Rutland
2017-02-06 16:33 ` [kernel-hardening] " Mark Rutland
2017-02-06 16:40 ` Ard Biesheuvel
2017-02-06 16:40 ` [kernel-hardening] " Ard Biesheuvel
2017-02-06 16:24 ` [PATCH 2/7] include: pe.h: add some missing definitions Ard Biesheuvel
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
2017-02-06 16:24 ` [PATCH 3/7] arm64: efi: move EFI header and related data to a separate .S file Ard Biesheuvel
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
2017-02-06 17:03 ` Mark Rutland
2017-02-06 17:03 ` [kernel-hardening] " Mark Rutland
2017-02-06 17:07 ` Ard Biesheuvel
2017-02-06 17:07 ` [kernel-hardening] " Ard Biesheuvel
2017-02-06 16:24 ` [PATCH 4/7] arm64: efi: ensure that the PE/COFF header pointer appears at offset 0x3c Ard Biesheuvel
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
2017-02-06 17:05 ` Mark Rutland
2017-02-06 17:05 ` [kernel-hardening] " Mark Rutland
2017-02-06 16:24 ` [PATCH 5/7] arm64: efi: remove pointless dummy .reloc section Ard Biesheuvel
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
2017-02-06 17:06 ` Mark Rutland
2017-02-06 17:06 ` [kernel-hardening] " Mark Rutland
2017-02-07 18:30 ` Peter Jones
2017-02-07 18:30 ` [kernel-hardening] " Peter Jones
2017-02-06 16:24 ` [PATCH 6/7] arm64: efi: replace open coded constants with symbolic ones Ard Biesheuvel
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
2017-02-06 17:13 ` Mark Rutland
2017-02-06 17:13 ` [kernel-hardening] " Mark Rutland
2017-02-06 16:24 ` [PATCH 7/7] arm64: efi: split Image code and data into separate PE/COFF sections Ard Biesheuvel
2017-02-06 16:24 ` [kernel-hardening] " Ard Biesheuvel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.