[PATCH] [DbgHelp]: protect PE's COFF table reading against bogus values in NTHEADER (fix for #22543)

Eric Pouech eric.pouech at orange.fr
Sat May 8 14:47:16 CDT 2010




A+
---

 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-patches mailing list