arrfab / rpms / shim

Forked from rpms/shim 4 years ago
Clone

Blame SOURCES/0001-Align-the-sections-we-re-loading-and-check-for-valid.patch

4210fa
From ebd5dd071bb3194f335044a2c4928d527ff073ad Mon Sep 17 00:00:00 2001
4210fa
From: Peter Jones <pjones@redhat.com>
4210fa
Date: Fri, 6 Feb 2015 17:48:07 -0500
4210fa
Subject: [PATCH] Align the sections we're loading, and check for validity
4210fa
 /after/ discarding.
4210fa
4210fa
Turns out a) the codegen on aarch64 generates code that has real
4210fa
alignment needs, and b) if we check the length of discardable sections
4210fa
before discarding them, we error for no reason.
4210fa
4210fa
So do the error checking in the right order, and always enforce some
4210fa
alignment because we know we have to.
4210fa
4210fa
Signed-off-by: Peter Jones <pjones@redhat.com>
4210fa
---
4210fa
 include/PeImage.h |  1 +
4210fa
 shim.c            | 28 +++++++++++++++++-----------
4210fa
 2 files changed, 18 insertions(+), 11 deletions(-)
4210fa
4210fa
diff --git a/include/PeImage.h b/include/PeImage.h
4210fa
index 133e11e..05f32ea 100644
4210fa
--- a/include/PeImage.h
4210fa
+++ b/include/PeImage.h
4210fa
@@ -778,6 +778,7 @@ typedef struct {
4210fa
 	UINTN SizeOfHeaders;
4210fa
 	UINT16 ImageType;
4210fa
 	UINT16 NumberOfSections;
4210fa
+	UINT32 SectionAlignment;
4210fa
 	EFI_IMAGE_SECTION_HEADER *FirstSection;
4210fa
 	EFI_IMAGE_DATA_DIRECTORY *RelocDir;
4210fa
 	EFI_IMAGE_DATA_DIRECTORY *SecDir;
4210fa
diff --git a/shim.c b/shim.c
4210fa
index 8076caa..6d577af 100644
4210fa
--- a/shim.c
4210fa
+++ b/shim.c
4210fa
@@ -1002,14 +1002,18 @@ static EFI_STATUS read_header(void *data, unsigned int datasize,
4210fa
 		context->NumberOfRvaAndSizes = PEHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes;
4210fa
 		context->SizeOfHeaders = PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders;
4210fa
 		context->ImageSize = PEHdr->Pe32Plus.OptionalHeader.SizeOfImage;
4210fa
+		context->SectionAlignment = PEHdr->Pe32Plus.OptionalHeader.SectionAlignment;
4210fa
 		OptHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER64);
4210fa
 	} else {
4210fa
 		context->NumberOfRvaAndSizes = PEHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes;
4210fa
 		context->SizeOfHeaders = PEHdr->Pe32.OptionalHeader.SizeOfHeaders;
4210fa
 		context->ImageSize = (UINT64)PEHdr->Pe32.OptionalHeader.SizeOfImage;
4210fa
+		context->SectionAlignment = PEHdr->Pe32.OptionalHeader.SectionAlignment;
4210fa
 		OptHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER32);
4210fa
 	}
4210fa
 
4210fa
+	if (context->SectionAlignment < 0x1000)
4210fa
+		context->SectionAlignment = 0x1000;
4210fa
 	context->NumberOfSections = PEHdr->Pe32.FileHeader.NumberOfSections;
4210fa
 
4210fa
 	if (EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES < context->NumberOfRvaAndSizes) {
4210fa
@@ -1128,7 +1132,8 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
4210fa
 		}
4210fa
 	}
4210fa
 
4210fa
-	buffer = AllocatePool(context.ImageSize);
4210fa
+	buffer = AllocatePool(context.ImageSize + context.SectionAlignment);
4210fa
+	buffer = ALIGN_POINTER(buffer, context.SectionAlignment);
4210fa
 
4210fa
 	if (!buffer) {
4210fa
 		perror(L"Failed to allocate image buffer\n");
4210fa
@@ -1159,16 +1164,6 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
4210fa
 
4210fa
 		base = ImageAddress (buffer, context.ImageSize, Section->VirtualAddress);
4210fa
 		end = ImageAddress (buffer, context.ImageSize, Section->VirtualAddress + size - 1);
4210fa
-		if (!base || !end) {
4210fa
-			perror(L"Invalid section size\n");
4210fa
-			return EFI_UNSUPPORTED;
4210fa
-		}
4210fa
-
4210fa
-		if (Section->VirtualAddress < context.SizeOfHeaders ||
4210fa
-				Section->PointerToRawData < context.SizeOfHeaders) {
4210fa
-			perror(L"Section is inside image headers\n");
4210fa
-			return EFI_UNSUPPORTED;
4210fa
-		}
4210fa
 
4210fa
 		/* We do want to process .reloc, but it's often marked
4210fa
 		 * discardable, so we don't want to memcpy it. */
4210fa
@@ -1194,6 +1189,17 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
4210fa
 			continue;
4210fa
 		}
4210fa
 
4210fa
+		if (!base || !end) {
4210fa
+			perror(L"Section %d has invalid size\n", i);
4210fa
+			return EFI_UNSUPPORTED;
4210fa
+		}
4210fa
+
4210fa
+		if (Section->VirtualAddress < context.SizeOfHeaders ||
4210fa
+				Section->PointerToRawData < context.SizeOfHeaders) {
4210fa
+			perror(L"Section %d is inside image headers\n", i);
4210fa
+			return EFI_UNSUPPORTED;
4210fa
+		}
4210fa
+
4210fa
 		if (Section->SizeOfRawData > 0)
4210fa
 			CopyMem(base, data + Section->PointerToRawData, size);
4210fa
 
4210fa
-- 
4210fa
2.1.0
4210fa