Andrey Turkin : kernel32: Catch invalid memory accesses in resource enumeration handlers.

Alexandre Julliard julliard at winehq.org
Mon Oct 5 09:54:31 CDT 2009


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

Author: Andrey Turkin <andrey.turkin at gmail.com>
Date:   Mon Oct  5 16:17:56 2009 +0400

kernel32: Catch invalid memory accesses in resource enumeration handlers.

---

 dlls/kernel32/resource.c |  119 ++++++++++++++++++++++++++++++----------------
 1 files changed, 78 insertions(+), 41 deletions(-)

diff --git a/dlls/kernel32/resource.c b/dlls/kernel32/resource.c
index 9feb672..d405b95 100644
--- a/dlls/kernel32/resource.c
+++ b/dlls/kernel32/resource.c
@@ -378,32 +378,42 @@ BOOL WINAPI EnumResourceNamesA( HMODULE hmod, LPCSTR type, ENUMRESNAMEPROCA lpfu
         goto done;
 
     et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
-    for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
+    __TRY
     {
-        if (et[i].u1.s1.NameIsString)
+        for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
         {
-            str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u1.s1.NameOffset);
-            newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
-            if (newlen + 1 > len)
+            if (et[i].u1.s1.NameIsString)
             {
-                len = newlen + 1;
-                HeapFree( GetProcessHeap(), 0, name );
-                if (!(name = HeapAlloc(GetProcessHeap(), 0, len + 1 )))
+                str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u1.s1.NameOffset);
+                newlen = WideCharToMultiByte(CP_ACP, 0, str->NameString, str->Length, NULL, 0, NULL, NULL);
+                if (newlen + 1 > len)
                 {
-                    ret = FALSE;
-                    break;
+                    len = newlen + 1;
+                    HeapFree( GetProcessHeap(), 0, name );
+                    if (!(name = HeapAlloc(GetProcessHeap(), 0, len + 1 )))
+                    {
+                        ret = FALSE;
+                        break;
+                    }
                 }
+                WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, name, len, NULL, NULL );
+                name[newlen] = 0;
+                ret = lpfun(hmod,type,name,lparam);
             }
-            WideCharToMultiByte( CP_ACP, 0, str->NameString, str->Length, name, len, NULL, NULL );
-            name[newlen] = 0;
-            ret = lpfun(hmod,type,name,lparam);
-        }
-        else
-        {
-            ret = lpfun( hmod, type, UIntToPtr(et[i].u1.s2.Id), lparam );
+            else
+            {
+                ret = lpfun( hmod, type, UIntToPtr(et[i].u1.s2.Id), lparam );
+            }
+            if (!ret) break;
         }
-        if (!ret) break;
     }
+    __EXCEPT_PAGE_FAULT
+    {
+        ret = FALSE;
+        status = STATUS_ACCESS_VIOLATION;
+    }
+    __ENDTRY
+
 done:
     HeapFree( GetProcessHeap(), 0, name );
     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
@@ -440,31 +450,40 @@ BOOL WINAPI EnumResourceNamesW( HMODULE hmod, LPCWSTR type, ENUMRESNAMEPROCW lpf
         goto done;
 
     et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
-    for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
+    __TRY
     {
-        if (et[i].u1.s1.NameIsString)
+        for (i = 0; i < resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries; i++)
         {
-            str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u1.s1.NameOffset);
-            if (str->Length + 1 > len)
+            if (et[i].u1.s1.NameIsString)
             {
-                len = str->Length + 1;
-                HeapFree( GetProcessHeap(), 0, name );
-                if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+                str = (const IMAGE_RESOURCE_DIR_STRING_U *)((const BYTE *)basedir + et[i].u1.s1.NameOffset);
+                if (str->Length + 1 > len)
                 {
-                    ret = FALSE;
-                    break;
+                    len = str->Length + 1;
+                    HeapFree( GetProcessHeap(), 0, name );
+                    if (!(name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+                    {
+                        ret = FALSE;
+                        break;
+                    }
                 }
+                memcpy(name, str->NameString, str->Length * sizeof (WCHAR));
+                name[str->Length] = 0;
+                ret = lpfun(hmod,type,name,lparam);
             }
-            memcpy(name, str->NameString, str->Length * sizeof (WCHAR));
-            name[str->Length] = 0;
-            ret = lpfun(hmod,type,name,lparam);
-        }
-        else
-        {
-            ret = lpfun( hmod, type, UIntToPtr(et[i].u1.s2.Id), lparam );
+            else
+            {
+                ret = lpfun( hmod, type, UIntToPtr(et[i].u1.s2.Id), lparam );
+            }
+            if (!ret) break;
         }
-        if (!ret) break;
     }
+    __EXCEPT_PAGE_FAULT
+    {
+        ret = FALSE;
+        status = STATUS_ACCESS_VIOLATION;
+    }
+    __ENDTRY
 done:
     HeapFree( GetProcessHeap(), 0, name );
     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
@@ -503,11 +522,20 @@ BOOL WINAPI EnumResourceLanguagesA( HMODULE hmod, LPCSTR type, LPCSTR name,
         goto done;
 
     et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
-    for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
+    __TRY
     {
-        ret = lpfun( hmod, type, name, et[i].u1.s2.Id, lparam );
-        if (!ret) break;
+        for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
+        {
+            ret = lpfun( hmod, type, name, et[i].u1.s2.Id, lparam );
+            if (!ret) break;
+        }
     }
+    __EXCEPT_PAGE_FAULT
+    {
+        ret = FALSE;
+        status = STATUS_ACCESS_VIOLATION;
+    }
+    __ENDTRY
 done:
     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
     if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
@@ -546,11 +574,20 @@ BOOL WINAPI EnumResourceLanguagesW( HMODULE hmod, LPCWSTR type, LPCWSTR name,
         goto done;
 
     et = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
-    for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
+    __TRY
     {
-        ret = lpfun( hmod, type, name, et[i].u1.s2.Id, lparam );
-        if (!ret) break;
+        for (i = 0; i < resdir->NumberOfNamedEntries + resdir->NumberOfIdEntries; i++)
+        {
+            ret = lpfun( hmod, type, name, et[i].u1.s2.Id, lparam );
+            if (!ret) break;
+        }
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        ret = FALSE;
+        status = STATUS_ACCESS_VIOLATION;
     }
+    __ENDTRY
 done:
     if (HIWORD(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
     if (HIWORD(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );




More information about the wine-cvs mailing list