Paul Gofman : advapi32: Handle exceptions from dereferencing invalid crypt objects' handles.

Alexandre Julliard julliard at winehq.org
Tue Feb 23 15:54:47 CST 2021


Module: wine
Branch: master
Commit: 992117ac9820a8c8d1174a62179c87ca7cf309ff
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=992117ac9820a8c8d1174a62179c87ca7cf309ff

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Tue Feb 23 16:07:32 2021 +0300

advapi32: Handle exceptions from dereferencing invalid crypt objects' handles.

Fixes crash on start in "Re:ZERO -Starting Life in Another World- The
Prophecy of the Throne".

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/advapi32/crypt.c       | 19 +++++++++++++++----
 dlls/advapi32/tests/crypt.c | 20 ++++++++++++++++++++
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/dlls/advapi32/crypt.c b/dlls/advapi32/crypt.c
index 6cdb5f3ecff..20c55558fa5 100644
--- a/dlls/advapi32/crypt.c
+++ b/dlls/advapi32/crypt.c
@@ -37,6 +37,7 @@
 #include "winreg.h"
 #include "rpc.h"
 #include "wine/debug.h"
+#include "wine/exception.h"
 #include "winternl.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
@@ -59,12 +60,22 @@ static HWND crypt_hWindow;
 
 static void *pointer_from_handle(UINT_PTR handle, DWORD magic)
 {
-    if (!handle || *(DWORD *)handle != magic)
+    void *ret = NULL;
+
+    __TRY
+    {
+        if (handle && *(DWORD *)handle == magic)
+            ret = (void *)handle;
+    }
+    __EXCEPT_PAGE_FAULT
     {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return NULL;
     }
-    return (void *)handle;
+    __ENDTRY
+
+    if (!ret)
+        SetLastError(ERROR_INVALID_PARAMETER);
+
+    return ret;
 }
 
 static PCRYPTPROV provider_from_handle(HCRYPTPROV handle)
diff --git a/dlls/advapi32/tests/crypt.c b/dlls/advapi32/tests/crypt.c
index a6e3d447ba8..6df47cd626b 100644
--- a/dlls/advapi32/tests/crypt.c
+++ b/dlls/advapi32/tests/crypt.c
@@ -154,6 +154,8 @@ static void test_CryptReleaseContext(void)
 
     ret = CryptContextAddRef(0, NULL, 0);
     ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
+    ret = CryptContextAddRef(0xdeadbeef, NULL, 0);
+    ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError());
 
     ret = CryptReleaseContext(prov, 0);
     ok(ret, "got %u\n", GetLastError());
@@ -272,6 +274,9 @@ static void test_incorrect_api_usage(void)
     ok (result, "%08x\n", GetLastError());
     if (!result) return;
 
+    /* Looks like native handles are just pointers. */
+    ok(!!*(void **)hProv, "Got zero *(void **)hProv.\n");
+
     result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash);
     ok (result, "%d\n", GetLastError());
     if (!result) return;
@@ -301,6 +306,9 @@ static void test_incorrect_api_usage(void)
     result = CryptDestroyHash(0);
     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
 
+    result = CryptCreateHash(0xdeadbeef, CALG_SHA, 0, 0, &hHash);
+    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
+
     result = CryptCreateHash(0, CALG_SHA, 0, 0, &hHash);
     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
 
@@ -310,13 +318,25 @@ static void test_incorrect_api_usage(void)
     dwLen = 1;
     result = CryptDecrypt(hKey, 0, TRUE, 0, &temp, &dwLen);
     ok (result, "%d\n", GetLastError());
+    result = CryptDecrypt(hKey, 0xdeadbeef, TRUE, 0, &temp, &dwLen);
+    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
     result = CryptDecrypt(0, 0, TRUE, 0, &temp, &dwLen);
     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
+    result = CryptDecrypt(0xdeadbeef, 0, TRUE, 0, &temp, &dwLen);
+    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
 
     result = CryptEncrypt(hKey, 0, TRUE, 0, &temp, &dwLen, sizeof(temp));
     ok (result, "%d\n", GetLastError());
+    result = CryptEncrypt(hKey, 0xdeadbeef, TRUE, 0, &temp, &dwLen, sizeof(temp));
+    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
     result = CryptEncrypt(0, 0, TRUE, 0, &temp, &dwLen, sizeof(temp));
     ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
+    result = CryptEncrypt(0xdeadbeef, 0, TRUE, 0, &temp, &dwLen, sizeof(temp));
+    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
+
+    dwLen = 1;
+    result = CryptExportKey(hKey, 0xdeadbeef, 0, 0, &temp, &dwLen);
+    ok (!result && GetLastError() == ERROR_INVALID_PARAMETER, "%d\n", GetLastError());
 
     result = CryptDestroyKey(hKey);
     ok (result, "%d\n", GetLastError());




More information about the wine-cvs mailing list