From dd387c42f0eaa26e7d158969fcbdd8cb0673d806 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Sun, 2 Jan 2005 20:09:39 +0000 Subject: [PATCH] Relaxed the validity checks for PE executables yet more (no limitation for the file layout anymore, as the memory manager doesn't really care and executables seen in the wild tend to be pretty eccentric). Documented with an ASSERT the fact that the file offset cannot overflow (MAXULONG + MAXULONG < MAXLONGLONG) svn path=/trunk/; revision=12734 --- reactos/ntoskrnl/mm/pe.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/reactos/ntoskrnl/mm/pe.c b/reactos/ntoskrnl/mm/pe.c index a7d71ae7551..316819b217d 100644 --- a/reactos/ntoskrnl/mm/pe.c +++ b/reactos/ntoskrnl/mm/pe.c @@ -74,6 +74,19 @@ static __inline BOOLEAN Intsafe_CanAddULongPtr return Addend1 <= (MAXULONG_PTR - Addend2); } +#ifndef MAXLONGLONG +#define MAXLONGLONG ((LONGLONG)((~((ULONGLONG)0)) >> 1)) +#endif + +static __inline BOOLEAN Intsafe_CanAddLong64 +( + IN LONG64 Addend1, + IN LONG64 Addend2 +) +{ + return Addend1 <= (MAXLONGLONG - Addend2); +} + static __inline BOOLEAN Intsafe_CanAddULong32 ( IN ULONG Addend1, @@ -210,7 +223,7 @@ NTSTATUS NTAPI PeFmtCreateSection LARGE_INTEGER lnOffset; PVOID pBuffer; ULONG nPrevVirtualEndOfSegment; - ULONG nPrevFileEndOfSegment; + ULONG nFileSizeOfHeaders; ULONG i; ASSERT(FileHeader); @@ -623,7 +636,7 @@ l_ReadHeaderFromFile: ASSERT(IsAligned(cbHeadersSize, nFileAlignment)); - if(!AlignUp(&nPrevFileEndOfSegment, cbHeadersSize, nFileAlignment)) + if(!AlignUp(&nFileSizeOfHeaders, cbHeadersSize, nFileAlignment)) DIE(("Cannot align the size of the section headers\n")); if(!AlignUp(&nPrevVirtualEndOfSegment, cbHeadersSize, nSectionAlignment)) @@ -632,7 +645,7 @@ l_ReadHeaderFromFile: pssSegments[0].FileOffset = 0; pssSegments[0].Protection = PAGE_READONLY; pssSegments[0].Length = nPrevVirtualEndOfSegment; - pssSegments[0].RawLength = nPrevFileEndOfSegment; + pssSegments[0].RawLength = nFileSizeOfHeaders; pssSegments[0].VirtualAddress = 0; pssSegments[0].Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA; pssSegments[0].WriteCopy = TRUE; @@ -665,12 +678,6 @@ l_ReadHeaderFromFile: if(!IsAligned(pishSectionHeaders[i].PointerToRawData, nFileAlignment)) DIE(("PointerToRawData[%u] is not aligned\n", i)); - /* sections must be contiguous, ordered by base address and non-overlapping */ -#if 0 - if(pishSectionHeaders[i].PointerToRawData != nPrevFileEndOfSegment) - DIE(("File gap between section %u and the previous\n", i)); -#endif - /* conversion */ pssSegments[i].FileOffset = pishSectionHeaders[i].PointerToRawData; pssSegments[i].RawLength = pishSectionHeaders[i].SizeOfRawData; @@ -681,6 +688,8 @@ l_ReadHeaderFromFile: ASSERT(pssSegments[i].RawLength == 0); } + ASSERT(Intsafe_CanAddLong64(pssSegments[i].FileOffset, pssSegments[i].RawLength)); + nCharacteristics = pishSectionHeaders[i].Characteristics; /* no explicit protection */ @@ -716,13 +725,6 @@ l_ReadHeaderFromFile: pssSegments[i].VirtualAddress = pishSectionHeaders[i].VirtualAddress; pssSegments[i].Characteristics = pishSectionHeaders[i].Characteristics; - /* ensure the executable is no larger than 4GB */ - if(pssSegments[i].RawLength != 0) - { - if(!Intsafe_AddULong32(&nPrevFileEndOfSegment, pssSegments[i].FileOffset, pssSegments[i].RawLength)) - DIE(("The executable is larger than 4GB\n")); - } - /* ensure the memory image is no larger than 4GB */ if(!Intsafe_AddULong32(&nPrevVirtualEndOfSegment, pssSegments[i].VirtualAddress, pssSegments[i].Length)) DIE(("The image is larger than 4GB\n"));