Module: wine Branch: master Commit: 516fc78a2b8afd57d5a1ad219c4886b3ea0d60f2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=516fc78a2b8afd57d5a1ad219c...
Author: Eric Pouech eric.pouech@orange.fr Date: Sat May 8 21:47:16 2010 +0200
dbghelp: Protect PE's COFF table reading against bogus values in NTHEADER.
---
dlls/dbghelp/pe_module.c | 49 ++++++++++++++++++++++++++++++++++++--------- 1 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/dlls/dbghelp/pe_module.c b/dlls/dbghelp/pe_module.c index baddaeb..cd2f248 100644 --- a/dlls/dbghelp/pe_module.c +++ b/dlls/dbghelp/pe_module.c @@ -172,6 +172,25 @@ unsigned pe_get_map_size(const struct image_section_map* ism) }
/****************************************************************** + * pe_is_valid_pointer_table + * + * Checks whether the PointerToSymbolTable and NumberOfSymbols in file_header contain + * valid information. + */ +static BOOL pe_is_valid_pointer_table(const IMAGE_NT_HEADERS* nthdr, const void* mapping) +{ + DWORD64 offset; + + /* is the iSym table inside file image ? */ + offset = (DWORD64)nthdr->FileHeader.PointerToSymbolTable; + offset += (DWORD64)nthdr->FileHeader.NumberOfSymbols * sizeof(IMAGE_SYMBOL); + if (offset > (DWORD64)nthdr->OptionalHeader.SizeOfImage) return FALSE; + /* is string table (following iSym table) inside file image ? */ + offset += *(DWORD*)((const char*)mapping + offset); + return offset <= (DWORD64)nthdr->OptionalHeader.SizeOfImage; +} + +/****************************************************************** * pe_map_file * * Maps an PE file into memory (and checks it's a real PE file) @@ -209,16 +228,26 @@ static BOOL pe_map_file(HANDLE file, struct image_file_map* fmap, enum module_ty } if (nthdr->FileHeader.PointerToSymbolTable && nthdr->FileHeader.NumberOfSymbols) { - /* FIXME ugly: should rather map the relevant content instead of copying it */ - const char* src = (const char*)mapping + - nthdr->FileHeader.PointerToSymbolTable + - nthdr->FileHeader.NumberOfSymbols * sizeof(IMAGE_SYMBOL); - char* dst; - DWORD sz = *(DWORD*)src; - - if ((dst = HeapAlloc(GetProcessHeap(), 0, sz))) - memcpy(dst, src, sz); - fmap->u.pe.strtable = dst; + if (pe_is_valid_pointer_table(nthdr, mapping)) + { + /* FIXME ugly: should rather map the relevant content instead of copying it */ + const char* src = (const char*)mapping + + nthdr->FileHeader.PointerToSymbolTable + + nthdr->FileHeader.NumberOfSymbols * sizeof(IMAGE_SYMBOL); + char* dst; + DWORD sz = *(DWORD*)src; + + if ((dst = HeapAlloc(GetProcessHeap(), 0, sz))) + memcpy(dst, src, sz); + fmap->u.pe.strtable = dst; + } + else + { + /* we have bad information here, wipe it out */ + fmap->u.pe.ntheader.FileHeader.PointerToSymbolTable = 0; + fmap->u.pe.ntheader.FileHeader.NumberOfSymbols = 0; + fmap->u.pe.strtable = NULL; + } } else fmap->u.pe.strtable = NULL; }