advapi32: Avoid a buffer overflow in CredUnmarshalCredentialW.

Hans Leidekker hans at codeweavers.com
Thu Nov 15 07:12:22 CST 2012


Spotted by Stefan Leichter.
---
 dlls/advapi32/cred.c       |    7 +++++--
 dlls/advapi32/tests/cred.c |    8 ++++++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/dlls/advapi32/cred.c b/dlls/advapi32/cred.c
index b2597b6..b735821 100644
--- a/dlls/advapi32/cred.c
+++ b/dlls/advapi32/cred.c
@@ -20,6 +20,7 @@
 
 #include <stdarg.h>
 #include <time.h>
+#include <limits.h>
 
 #ifdef __APPLE__
 # include <Security/SecKeychain.h>
@@ -2102,7 +2103,7 @@ static BOOL cred_decode( const WCHAR *cred, unsigned int len, char *buf )
  */
 BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVOID *out )
 {
-    unsigned int len, buflen, size;
+    unsigned int len, buflen;
 
     TRACE("%s, %p, %p\n", debugstr_w(cred), type, out);
 
@@ -2134,8 +2135,10 @@ BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVO
     case UsernameTargetCredential:
     {
         USERNAME_TARGET_CREDENTIAL_INFO *target;
+        ULONGLONG size = 0;
 
-        if (len < 9 || !cred_decode( cred + 3, 6, (char *)&size ) || !size || size % sizeof(WCHAR))
+        if (len < 9 || !cred_decode( cred + 3, 6, (char *)&size ) ||
+            !size || size % sizeof(WCHAR) || size > INT_MAX)
         {
             SetLastError( ERROR_INVALID_PARAMETER );
             return FALSE;
diff --git a/dlls/advapi32/tests/cred.c b/dlls/advapi32/tests/cred.c
index 3d37a3c..83212c5 100644
--- a/dlls/advapi32/tests/cred.c
+++ b/dlls/advapi32/tests/cred.c
@@ -670,6 +670,14 @@ static void test_CredUnmarshalCredentialA(void)
     ok( username->UserName != NULL, "UserName is NULL\n" );
     ok( !lstrcmpW( username->UserName, testW ), "got %s\n", wine_dbgstr_w(username->UserName) );
     pCredFree( username );
+
+    type = 0;
+    username = NULL;
+    SetLastError( 0xdeadbeef );
+    ret = pCredUnmarshalCredentialA( "@@CA-----0BQZAMHA0BA", &type, (void **)&username );
+    error = GetLastError();
+    ok( !ret, "unexpected success\n" );
+    ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
 }
 
 static void test_CredIsMarshaledCredentialA(void)
-- 
1.7.10.4






More information about the wine-patches mailing list