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