[RFC PATCH 4/4] efi: x86: Split PE/COFF .text section into .text and .data

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

 



Modern PE loader implementations used by EFI will honour the PE section
permission attributes, and so we can use them to avoid mappings that are
writable and executable at the same time.

Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx>
---
 arch/x86/boot/header.S      | 17 ++++++++++++++++
 arch/x86/boot/tools/build.c | 21 +++++++++++++++-----
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 4f1e1791cda4d316..a8ff8bbb17bca7d7 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -253,6 +253,23 @@ section_table:
 		IMAGE_SCN_MEM_READ		| \
 		IMAGE_SCN_MEM_EXECUTE		# Characteristics
 
+	.ascii	".data"
+	.byte	0
+	.byte	0
+	.byte	0
+	.long	0
+	.long	0x0				# startup_{32,64}
+	.long	0				# Size of initialized data
+						# on disk
+	.long	0x0				# startup_{32,64}
+	.long	0				# PointerToRelocations
+	.long	0				# PointerToLineNumbers
+	.word	0				# NumberOfRelocations
+	.word	0				# NumberOfLineNumbers
+	.long	IMAGE_SCN_CNT_INITIALIZED_DATA	| \
+		IMAGE_SCN_MEM_READ		| \
+		IMAGE_SCN_MEM_WRITE		# Characteristics
+
 	.set	section_count, (. - section_table) / 40
 #endif /* CONFIG_EFI_STUB */
 
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index 883e6359221cd588..b449c82feaadf2b8 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -119,6 +119,7 @@ static unsigned long efi_boot_params;
 static unsigned long kernel_info;
 static unsigned long startup_64;
 static unsigned long _ehead;
+static unsigned long _data;
 static unsigned long _end;
 
 /*----------------------------------------------------------------------*/
@@ -347,10 +348,15 @@ static unsigned int update_pecoff_sections(unsigned int text_start, unsigned int
 	init_sz	+= CONFIG_PHYSICAL_ALIGN;
 
 	/*
-	 * Size of code: Subtract the size of the first sector (512 bytes)
-	 * which includes the header.
+	 * Size of code: the size of the combined .text/.rodata section, which
+	 * ends at the _data marker symbol.
 	 */
-	put_unaligned_le32(text_sz + bss_sz, &hdr->text_size);
+	put_unaligned_le32(_data, &hdr->text_size);
+
+	/*
+	 * Size of data: the size of the combined .data/.bss section.
+	 */
+	put_unaligned_le32(text_sz - _data + bss_sz, &hdr->data_size);
 
 	/* Size of image */
 	put_unaligned_le32(init_sz, &hdr->image_size);
@@ -360,9 +366,13 @@ static unsigned int update_pecoff_sections(unsigned int text_start, unsigned int
 	 */
 	put_unaligned_le32(text_start + efi_pe_entry, &hdr->entry_point);
 
-	update_pecoff_section_header_fields(".text", text_start, text_sz + bss_sz,
-					    text_sz, text_start);
+	update_pecoff_section_header_fields(".text", text_start, _data,
+					    _data, text_start);
 
+	update_pecoff_section_header_fields(".data", text_start + _data,
+					    text_sz - _data + bss_sz,
+					    text_sz - _data,
+					    text_start + _data);
 	return text_start + file_sz;
 }
 
@@ -455,6 +465,7 @@ static void parse_zoffset(char *fname)
 		PARSE_ZOFS(p, kernel_info);
 		PARSE_ZOFS(p, startup_64);
 		PARSE_ZOFS(p, _ehead);
+		PARSE_ZOFS(p, _data);
 		PARSE_ZOFS(p, _end);
 
 		p = strchr(p, '\n');
-- 
2.39.2




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux