summaryrefslogtreecommitdiff
path: root/shim.c
diff options
context:
space:
mode:
Diffstat (limited to 'shim.c')
-rw-r--r--shim.c86
1 files changed, 27 insertions, 59 deletions
diff --git a/shim.c b/shim.c
index 3d1febbc..537177d0 100644
--- a/shim.c
+++ b/shim.c
@@ -102,7 +102,7 @@ typedef struct {
/*
* Perform basic bounds checking of the intra-image pointers
*/
-static void *ImageAddress (void *image, unsigned int size, unsigned int address)
+static void *ImageAddress (void *image, int size, unsigned int address)
{
if (address > size)
return NULL;
@@ -483,19 +483,18 @@ static BOOLEAN secure_mode (void)
* Calculate the SHA1 and SHA256 hashes of a binary
*/
-static EFI_STATUS generate_hash (char *data, int datasize_in,
+static EFI_STATUS generate_hash (char *data, int datasize,
PE_COFF_LOADER_IMAGE_CONTEXT *context,
UINT8 *sha256hash, UINT8 *sha1hash)
{
unsigned int sha256ctxsize, sha1ctxsize;
- unsigned int size;
+ unsigned int size = datasize;
void *sha256ctx = NULL, *sha1ctx = NULL;
char *hashbase;
unsigned int hashsize;
unsigned int SumOfBytesHashed, SumOfSectionBytes;
unsigned int index, pos;
- unsigned int datasize;
EFI_IMAGE_SECTION_HEADER *Section;
EFI_IMAGE_SECTION_HEADER *SectionHeader = NULL;
EFI_IMAGE_SECTION_HEADER *SectionCache;
@@ -507,12 +506,6 @@ static EFI_STATUS generate_hash (char *data, int datasize_in,
sha1ctxsize = Sha1GetContextSize();
sha1ctx = AllocatePool(sha1ctxsize);
- if (datasize_in < 0) {
- Print(L"Invalid data size\n");
- return EFI_INVALID_PARAMETER;
- }
- size = datasize = (unsigned int)datasize_in;
-
if (!sha256ctx || !sha1ctx) {
Print(L"Unable to allocate memory for hash context\n");
return EFI_OUT_OF_RESOURCES;
@@ -563,29 +556,22 @@ static EFI_STATUS generate_hash (char *data, int datasize_in,
/* Sort sections */
SumOfBytesHashed = context->PEHdr->Pe32Plus.OptionalHeader.SizeOfHeaders;
- /* Validate section locations and sizes */
+ Section = (EFI_IMAGE_SECTION_HEADER *) (
+ (char *)context->PEHdr + sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ context->PEHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+
+ SectionCache = Section;
+
for (index = 0, SumOfSectionBytes = 0; index < context->PEHdr->Pe32.FileHeader.NumberOfSections; index++, SectionCache++) {
- EFI_IMAGE_SECTION_HEADER *SectionPtr;
-
- /* Validate SectionPtr is within image */
- SectionPtr = ImageAddress(data, datasize,
- sizeof (UINT32) +
- sizeof (EFI_IMAGE_FILE_HEADER) +
- context->PEHdr->Pe32.FileHeader.SizeOfOptionalHeader +
- (index * sizeof(*SectionPtr)));
- if (!SectionPtr) {
- Print(L"Malformed section %d\n", index);
- status = EFI_INVALID_PARAMETER;
- goto done;
- }
- /* Validate section size is within image. */
- if (SectionPtr->SizeOfRawData >
- datasize - SumOfBytesHashed - SumOfSectionBytes) {
- Print(L"Malformed section %d size\n", index);
- status = EFI_INVALID_PARAMETER;
- goto done;
- }
- SumOfSectionBytes += SectionPtr->SizeOfRawData;
+ SumOfSectionBytes += SectionCache->SizeOfRawData;
+ }
+
+ if (SumOfSectionBytes >= datasize) {
+ Print(L"Malformed binary: %x %x\n", SumOfSectionBytes, size);
+ status = EFI_INVALID_PARAMETER;
+ goto done;
}
SectionHeader = (EFI_IMAGE_SECTION_HEADER *) AllocateZeroPool (sizeof (EFI_IMAGE_SECTION_HEADER) * context->PEHdr->Pe32.FileHeader.NumberOfSections);
@@ -595,11 +581,6 @@ static EFI_STATUS generate_hash (char *data, int datasize_in,
goto done;
}
- /* Already validated above */
- Section = ImageAddress(data, datasize, sizeof (UINT32) +
- sizeof (EFI_IMAGE_FILE_HEADER) +
- context->PEHdr->Pe32.FileHeader.SizeOfOptionalHeader);
-
/* Sort the section headers */
for (index = 0; index < context->PEHdr->Pe32.FileHeader.NumberOfSections; index++) {
pos = index;
@@ -617,8 +598,8 @@ static EFI_STATUS generate_hash (char *data, int datasize_in,
if (Section->SizeOfRawData == 0) {
continue;
}
- hashbase = ImageAddress(data, size,
- Section->PointerToRawData);
+ hashbase = ImageAddress(data, size, Section->PointerToRawData);
+ hashsize = (unsigned int) Section->SizeOfRawData;
if (!hashbase) {
Print(L"Malformed section header\n");
@@ -626,15 +607,6 @@ static EFI_STATUS generate_hash (char *data, int datasize_in,
goto done;
}
- /* Verify hashsize within image. */
- if (Section->SizeOfRawData >
- datasize - Section->PointerToRawData) {
- Print(L"Malformed section raw size %d\n", index);
- status = EFI_INVALID_PARAMETER;
- goto done;
- }
- hashsize = (unsigned int) Section->SizeOfRawData;
-
if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
!(Sha1Update(sha1ctx, hashbase, hashsize))) {
Print(L"Unable to generate hash\n");
@@ -645,10 +617,10 @@ static EFI_STATUS generate_hash (char *data, int datasize_in,
}
/* Hash all remaining data */
- if (datasize > SumOfBytesHashed) {
+ if (size > SumOfBytesHashed) {
hashbase = data + SumOfBytesHashed;
hashsize = (unsigned int)(
- datasize -
+ size -
context->PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
SumOfBytesHashed);
@@ -878,8 +850,7 @@ static EFI_STATUS read_header(void *data, unsigned int datasize,
return EFI_UNSUPPORTED;
}
- if ((unsigned long)((UINT8 *)context->SecDir - (UINT8 *)data) >
- (datasize - sizeof(EFI_IMAGE_DATA_DIRECTORY))) {
+ if (((UINT8 *)context->SecDir - (UINT8 *)data) > (datasize - sizeof(EFI_IMAGE_DATA_DIRECTORY))) {
Print(L"Invalid image\n");
return EFI_UNSUPPORTED;
}
@@ -899,8 +870,7 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
{
EFI_STATUS efi_status;
char *buffer;
- int i;
- unsigned int size;
+ int i, size;
EFI_IMAGE_SECTION_HEADER *Section;
char *base, *end;
PE_COFF_LOADER_IMAGE_CONTEXT context;
@@ -1077,8 +1047,7 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath,
{
EFI_DEVICE_PATH *devpath;
EFI_HANDLE device;
- unsigned int i;
- int j, last = -1;
+ int i, j, last = -1;
unsigned int pathlen = 0;
EFI_STATUS efi_status = EFI_SUCCESS;
CHAR16 *bootpath;
@@ -1633,10 +1602,9 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
EFI_STATUS status;
EFI_LOADED_IMAGE *li;
CHAR16 *start = NULL, *c;
- unsigned int i;
- int remaining_size = 0;
+ int i, remaining_size = 0;
CHAR16 *loader_str = NULL;
- unsigned int loader_len = 0;
+ int loader_len = 0;
second_stage = DEFAULT_LOADER;
load_options = NULL;