From b732246b875d604d50e335e4431d52f8cf37fd1d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 13 Mar 2012 17:15:28 +0000 Subject: [PATCH] * hookapi.cc (hook_or_detect_cygwin): Change condition when to use importRVAMaxSize or importRVASize for the mapping size. Make sure to map never more than the section size. Change comments accordingly. --- winsup/cygwin/ChangeLog | 6 ++++++ winsup/cygwin/hookapi.cc | 24 +++++++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 95ff1a24d..d0f74cf61 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2012-03-13 Corinna Vinschen + + * hookapi.cc (hook_or_detect_cygwin): Change condition when to use + importRVAMaxSize or importRVASize for the mapping size. Make sure + to map never more than the section size. Change comments accordingly. + 2012-03-13 Corinna Vinschen * include/netdb.h (h_errno): Add self-referencing macro and comment. diff --git a/winsup/cygwin/hookapi.cc b/winsup/cygwin/hookapi.cc index a56538dc6..11280c6a2 100644 --- a/winsup/cygwin/hookapi.cc +++ b/winsup/cygwin/hookapi.cc @@ -310,12 +310,14 @@ hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys, HANDLE h) built with Visual Studio. When built with gcc, importRVASize contains the size of the import RVA table plus the size of the referenced string table with the DLL names. When built with VS, it only contains - the size of the naked import RVA table. importRVAMaxSize contains the - size of the reminder of the section. If that's less than 64K, we're - good. Otherwise the executable is potentially *very* big. In that - case we only map the naked import RVA table and ... */ + the size of the naked import RVA table. The following code handles + the situation. importRVAMaxSize contains the size of the remainder + of the section. If the difference between importRVAMaxSize and + importRVASize is less than 64K, we just use importRVAMaxSize to + compute the size of the memory map. Otherwise the executable may be + very big. In that case we only map the import RVA table and ... */ DWORD size = importRVA - offset - + ((importRVA - offset + importRVAMaxSize + + ((importRVAMaxSize - importRVASize <= wincap.allocation_granularity ()) ? importRVAMaxSize : importRVASize); map = (char *) MapViewOfFile (h, FILE_MAP_READ, 0, offset, size); @@ -323,18 +325,18 @@ hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys, HANDLE h) return NULL; pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, map, importRVA - offset); /* ... carefully check the required size to fit the string table into - the map as well. Allow NAME_MAX bytes for the DLL name. There's a - slim chance that the allocation will fail, if the string table is - right at the end of the last section in the file, but that's very - unlikely. */ - if (importRVA - offset + importRVAMaxSize > wincap.allocation_granularity ()) + the map as well. Allow NAME_MAX bytes for the DLL name, but don't + go beyond the remainder of the section. */ + if (importRVAMaxSize - importRVASize > wincap.allocation_granularity ()) { DWORD newsize = size; for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++) if (pd->Name - delta - offset + (NAME_MAX + 1) > newsize) newsize = pd->Name - delta - offset + (NAME_MAX + 1); - if (newsize > size ) + if (newsize > size) { + if (newsize > importRVA - offset + importRVAMaxSize) + newsize = importRVA - offset + importRVAMaxSize; UnmapViewOfFile (map); map = (char *) MapViewOfFile (h, FILE_MAP_READ, 0, offset, newsize);