|
|
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 |
|