diff mbox series

[15/17] x86/boot: Split off PE/COFF .data section

Message ID 20230818134422.380032-16-ardb@kernel.org
State Accepted
Commit 34951f3c28bdf6481d949a20413b2ce7693687b2
Headers show
Series x86/boot: Rework PE header generation | expand

Commit Message

Ard Biesheuvel Aug. 18, 2023, 1:44 p.m. UTC
Describe the code and data of the decompressor binary using separate
.text and .data PE/COFF sections, so that we will be able to map them
using restricted permissions once we increase the section and file
alignment sufficiently. This avoids the need for memory mappings that
are writable and executable at the same time, which is something that
is best avoided for security reasons.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/x86/boot/Makefile |  2 +-
 arch/x86/boot/header.S | 19 +++++++++++++++----
 2 files changed, 16 insertions(+), 5 deletions(-)

Comments

Marvin Häuser Aug. 18, 2023, 2:35 p.m. UTC | #1
Hi Ard,

Thanks for your effort! Not sure what the documentation policies are, but might it be worth mentioning that we cannot have .rdata at this time, because current-gen EFI will map it as RW?

Best regards,
Marvin

> On Aug 18, 2023, at 15:45, Ard Biesheuvel <ardb@kernel.org> wrote:
> Describe the code and data of the decompressor binary using separate
> .text and .data PE/COFF sections, so that we will be able to map them
> using restricted permissions once we increase the section and file
> alignment sufficiently. This avoids the need for memory mappings that
> are writable and executable at the same time, which is something that
> is best avoided for security reasons.
> 
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
> arch/x86/boot/Makefile |  2 +-
> arch/x86/boot/header.S | 19 +++++++++++++++----
> 2 files changed, 16 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
> index b26e30a2d865f72d..50c50fce646e2417 100644
> --- a/arch/x86/boot/Makefile
> +++ b/arch/x86/boot/Makefile
> @@ -90,7 +90,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
> 
> SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
> 
> -sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|efi.._stub_entry\|efi\(32\)\?_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|_edata\|z_.*\)$$/\#define ZO_\2 0x\1/p'
> +sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|efi.._stub_entry\|efi\(32\)\?_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|_e\?data\|z_.*\)$$/\#define ZO_\2 0x\1/p'
> 
> quiet_cmd_zoffset = ZOFFSET $@
>       cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
> diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
> index ccfb7a7d8c29275e..25dda40dacb52292 100644
> --- a/arch/x86/boot/header.S
> +++ b/arch/x86/boot/header.S
> @@ -79,9 +79,9 @@ optional_header:
>    .byte    0x02                # MajorLinkerVersion
>    .byte    0x14                # MinorLinkerVersion
> 
> -    .long    setup_size + ZO__end - 0x200    # SizeOfCode
> +    .long    ZO__data            # SizeOfCode
> 
> -    .long    0                # SizeOfInitializedData
> +    .long    ZO__end - ZO__data        # SizeOfInitializedData
>    .long    0                # SizeOfUninitializedData
> 
>    .long    setup_size + ZO_efi_pe_entry    # AddressOfEntryPoint
> @@ -182,9 +182,9 @@ section_table:
>    .byte    0
>    .byte    0
>    .byte    0
> -    .long    ZO__end
> +    .long    ZO__data
>    .long    setup_size
> -    .long    ZO__edata            # Size of initialized data
> +    .long    ZO__data            # Size of initialized data
>                        # on disk
>    .long    setup_size
>    .long    0                # PointerToRelocations
> @@ -195,6 +195,17 @@ section_table:
>        IMAGE_SCN_MEM_READ        | \
>        IMAGE_SCN_MEM_EXECUTE        # Characteristics
> 
> +    .ascii    ".data\0\0\0"
> +    .long    ZO__end - ZO__data        # VirtualSize
> +    .long    setup_size + ZO__data        # VirtualAddress
> +    .long    ZO__edata - ZO__data        # SizeOfRawData
> +    .long    setup_size + ZO__data        # PointerToRawData
> +
> +    .long    0, 0, 0
> +    .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 */
> 
> -- 
> 2.39.2
Ard Biesheuvel Sept. 7, 2023, 1:44 p.m. UTC | #2
On Fri, 18 Aug 2023 at 16:35, Marvin Häuser <mhaeuser@posteo.de> wrote:
>
> Hi Ard,
>
> Thanks for your effort! Not sure what the documentation policies are, but might it be worth mentioning that we cannot have .rdata at this time, because current-gen EFI will map it as RW?
>

Yeah I'll mention this in the next version.


> Best regards,
> Marvin
>
> > On Aug 18, 2023, at 15:45, Ard Biesheuvel <ardb@kernel.org> wrote:
> > Describe the code and data of the decompressor binary using separate
> > .text and .data PE/COFF sections, so that we will be able to map them
> > using restricted permissions once we increase the section and file
> > alignment sufficiently. This avoids the need for memory mappings that
> > are writable and executable at the same time, which is something that
> > is best avoided for security reasons.
> >
> > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > ---
> > arch/x86/boot/Makefile |  2 +-
> > arch/x86/boot/header.S | 19 +++++++++++++++----
> > 2 files changed, 16 insertions(+), 5 deletions(-)
> >
> > diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
> > index b26e30a2d865f72d..50c50fce646e2417 100644
> > --- a/arch/x86/boot/Makefile
> > +++ b/arch/x86/boot/Makefile
> > @@ -90,7 +90,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
> >
> > SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
> >
> > -sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|efi.._stub_entry\|efi\(32\)\?_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|_edata\|z_.*\)$$/\#define ZO_\2 0x\1/p'
> > +sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|efi.._stub_entry\|efi\(32\)\?_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|_e\?data\|z_.*\)$$/\#define ZO_\2 0x\1/p'
> >
> > quiet_cmd_zoffset = ZOFFSET $@
> >       cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
> > diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
> > index ccfb7a7d8c29275e..25dda40dacb52292 100644
> > --- a/arch/x86/boot/header.S
> > +++ b/arch/x86/boot/header.S
> > @@ -79,9 +79,9 @@ optional_header:
> >    .byte    0x02                # MajorLinkerVersion
> >    .byte    0x14                # MinorLinkerVersion
> >
> > -    .long    setup_size + ZO__end - 0x200    # SizeOfCode
> > +    .long    ZO__data            # SizeOfCode
> >
> > -    .long    0                # SizeOfInitializedData
> > +    .long    ZO__end - ZO__data        # SizeOfInitializedData
> >    .long    0                # SizeOfUninitializedData
> >
> >    .long    setup_size + ZO_efi_pe_entry    # AddressOfEntryPoint
> > @@ -182,9 +182,9 @@ section_table:
> >    .byte    0
> >    .byte    0
> >    .byte    0
> > -    .long    ZO__end
> > +    .long    ZO__data
> >    .long    setup_size
> > -    .long    ZO__edata            # Size of initialized data
> > +    .long    ZO__data            # Size of initialized data
> >                        # on disk
> >    .long    setup_size
> >    .long    0                # PointerToRelocations
> > @@ -195,6 +195,17 @@ section_table:
> >        IMAGE_SCN_MEM_READ        | \
> >        IMAGE_SCN_MEM_EXECUTE        # Characteristics
> >
> > +    .ascii    ".data\0\0\0"
> > +    .long    ZO__end - ZO__data        # VirtualSize
> > +    .long    setup_size + ZO__data        # VirtualAddress
> > +    .long    ZO__edata - ZO__data        # SizeOfRawData
> > +    .long    setup_size + ZO__data        # PointerToRawData
> > +
> > +    .long    0, 0, 0
> > +    .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 */
> >
> > --
> > 2.39.2
>
diff mbox series

Patch

diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index b26e30a2d865f72d..50c50fce646e2417 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -90,7 +90,7 @@  $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
 
 SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
 
-sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|efi.._stub_entry\|efi\(32\)\?_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|_edata\|z_.*\)$$/\#define ZO_\2 0x\1/p'
+sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|efi.._stub_entry\|efi\(32\)\?_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|_e\?data\|z_.*\)$$/\#define ZO_\2 0x\1/p'
 
 quiet_cmd_zoffset = ZOFFSET $@
       cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index ccfb7a7d8c29275e..25dda40dacb52292 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -79,9 +79,9 @@  optional_header:
 	.byte	0x02				# MajorLinkerVersion
 	.byte	0x14				# MinorLinkerVersion
 
-	.long	setup_size + ZO__end - 0x200	# SizeOfCode
+	.long	ZO__data			# SizeOfCode
 
-	.long	0				# SizeOfInitializedData
+	.long	ZO__end - ZO__data		# SizeOfInitializedData
 	.long	0				# SizeOfUninitializedData
 
 	.long	setup_size + ZO_efi_pe_entry	# AddressOfEntryPoint
@@ -182,9 +182,9 @@  section_table:
 	.byte	0
 	.byte	0
 	.byte	0
-	.long	ZO__end
+	.long	ZO__data
 	.long	setup_size
-	.long	ZO__edata			# Size of initialized data
+	.long	ZO__data			# Size of initialized data
 						# on disk
 	.long	setup_size
 	.long	0				# PointerToRelocations
@@ -195,6 +195,17 @@  section_table:
 		IMAGE_SCN_MEM_READ		| \
 		IMAGE_SCN_MEM_EXECUTE		# Characteristics
 
+	.ascii	".data\0\0\0"
+	.long	ZO__end - ZO__data		# VirtualSize
+	.long	setup_size + ZO__data		# VirtualAddress
+	.long	ZO__edata - ZO__data		# SizeOfRawData
+	.long	setup_size + ZO__data		# PointerToRawData
+
+	.long	0, 0, 0
+	.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 */