[PATCH] oleaut32: Don't store non-heap-allocated strings in the BSTR cache

Andrew Eikum aeikum at codeweavers.com
Wed Dec 23 08:48:26 CST 2015


An application was passing a static string to SysFreeString.
SysFreeString would store the pointer in the BSTR cache. Eventually
the pointer would be re-used by SysAllocString and crash the program.

The approach I took to fix this was to determine if the pointer
belongs to a module. If so, then it can't be on the heap, and so we
didn't allocate it and we shouldn't try to free it or store it in the
cache.

Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
 dlls/oleaut32/oleaut.c        | 8 ++++++++
 dlls/oleaut32/tests/vartype.c | 3 +++
 2 files changed, 11 insertions(+)

diff --git a/dlls/oleaut32/oleaut.c b/dlls/oleaut32/oleaut.c
index 0352215..7a2768e 100644
--- a/dlls/oleaut32/oleaut.c
+++ b/dlls/oleaut32/oleaut.c
@@ -251,12 +251,20 @@ BSTR WINAPI SysAllocString(LPCOLESTR str)
  */
 void WINAPI SysFreeString(BSTR str)
 {
+    HMODULE module = NULL;
     bstr_cache_entry_t *cache_entry;
     bstr_t *bstr;
 
     if(!str)
         return;
 
+    GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+            str, &module);
+    if(module) {
+        WARN("freed string %p is not allocated on the heap, but owned by module %p\n", str, module);
+        return;
+    }
+
     bstr = bstr_from_str(str);
     cache_entry = get_cache_entry(bstr->size+sizeof(WCHAR));
     if(cache_entry) {
diff --git a/dlls/oleaut32/tests/vartype.c b/dlls/oleaut32/tests/vartype.c
index 7cbb059..0669ef0 100644
--- a/dlls/oleaut32/tests/vartype.c
+++ b/dlls/oleaut32/tests/vartype.c
@@ -6324,6 +6324,9 @@ static void test_bstr_cache(void)
         return;
     }
 
+    /* this should not crash the tests */
+    SysFreeString((BSTR)testW);
+
     str = SysAllocString(testW);
     /* This should put the string into cache */
     SysFreeString(str);
-- 
2.6.4




More information about the wine-patches mailing list