Eric Pouech : dbghelp: Protect PE' s COFF table reading against bogus values in NTHEADER.

Alexandre Julliard julliard at winehq.org
Mon May 10 11:59:15 CDT 2010


Module: wine
Branch: master
Commit: 516fc78a2b8afd57d5a1ad219c4886b3ea0d60f2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=516fc78a2b8afd57d5a1ad219c4886b3ea0d60f2

Author: Eric Pouech <eric.pouech at 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;
         }




More information about the wine-cvs mailing list