From: "Erich E. Hoover" Subject: [PATCH 1/1] ntdll: Fix section header heap deadlock (try 3). Message-Id: Date: Thu, 5 Apr 2012 10:38:07 -0600 Real Name: Erich Hoover Description: Use a local fixed-size buffer to keep the process heap from potentially deadlocking (Bug #30356). Uses a buffer big enough for 96 sections, since MSDN indicates that that is the maximum that the loader supports. Changelog: ntdll: Fix section header heap deadlock. From eef412560cbb5db71c323a806f61646099c90bae Mon Sep 17 00:00:00 2001 From: Erich Hoover Date: Thu, 5 Apr 2012 10:36:33 -0600 Subject: ntdll: Fix section header heap deadlock. --- dlls/ntdll/virtual.c | 12 +++--------- 1 files changed, 3 insertions(+), 9 deletions(-) diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 7c2b1a9..d67f2d5 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -1122,7 +1122,8 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz { IMAGE_DOS_HEADER *dos; IMAGE_NT_HEADERS *nt; - IMAGE_SECTION_HEADER *sec, *sections = NULL; + IMAGE_SECTION_HEADER sections[96]; + IMAGE_SECTION_HEADER *sec; IMAGE_DATA_DIRECTORY *imports; NTSTATUS status = STATUS_CONFLICTING_ADDRESSES; int i; @@ -1168,15 +1169,10 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz memset( ptr + header_size, 0, header_end - (ptr + header_size) ); if ((char *)(nt + 1) > header_end) goto error; header_start = (char*)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader; + if (nt->FileHeader.NumberOfSections > sizeof(sections)/sizeof(*sections)) goto error; if (header_start + sizeof(*sections) * nt->FileHeader.NumberOfSections > header_end) goto error; /* Some applications (e.g. the Steam version of Borderlands) map over the top of the section headers, * copying the headers into local memory is necessary to properly load such applications. */ - sections = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*sections) * nt->FileHeader.NumberOfSections); - if (!sections) - { - status = STATUS_NO_MEMORY; - goto error; - } memcpy(sections, header_start, sizeof(*sections) * nt->FileHeader.NumberOfSections); sec = sections; @@ -1374,7 +1370,6 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz } done: - RtlFreeHeap( GetProcessHeap(), 0, sections ); view->mapping = dup_mapping; view->map_protect = map_vprot; server_leave_uninterrupted_section( &csVirtual, &sigset ); @@ -1387,7 +1382,6 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz return STATUS_SUCCESS; error: - RtlFreeHeap( GetProcessHeap(), 0, sections ); if (view) delete_view( view ); server_leave_uninterrupted_section( &csVirtual, &sigset ); if (dup_mapping) NtClose( dup_mapping ); -- 1.7.5.4