[1/5] advapi32: Fix stack corruption in CredIsMarshaledCredentialW.

Thomas Faber thomas.faber at reactos.org
Sat Mar 29 05:54:50 CDT 2014


In its currrent implementation, cred_decode with input length 6 writes
6 bytes to the output buffer. This overflows the DWORD passed in
CredIsMarshaledCredentialW.
CredUnmarshalCredential uses an ULONGLONG initialized to 0 to work
around this problem, however the correct solution is for the base64
decoder not to overflow its output buffer.

This fixes cred_decode to behave like a proper base64 decoder. No
callers depend on these extra nulls (the CertCredentialCase in fact
used a +2-sized buffer to cope with this same overflow).

The following patches address issues found while debugging this problem
and verifying the fix.
-------------- next part --------------
From 143c4703549cf6010237905275271f071b4e08ac Mon Sep 17 00:00:00 2001
From: Thomas Faber <thomas.faber at reactos.org>
Date: Fri, 20 Dec 2013 00:17:35 +0100
Subject: advapi32: Fix stack corruption in CredIsMarshaledCredentialW.

---
 dlls/advapi32/cred.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/dlls/advapi32/cred.c b/dlls/advapi32/cred.c
index 3bfc885..f407c0d 100644
--- a/dlls/advapi32/cred.c
+++ b/dlls/advapi32/cred.c
@@ -2049,7 +2049,6 @@ static BOOL cred_decode( const WCHAR *cred, unsigned int len, char *buf )
 
         buf[i + 0] = (c1 << 6) | c0;
         buf[i + 1] = (c2 << 4) | (c1 >> 2);
-        buf[i + 2] = c2 >> 4;
     }
     else if (len == 2)
     {
@@ -2057,16 +2056,10 @@ static BOOL cred_decode( const WCHAR *cred, unsigned int len, char *buf )
         if ((c1 = char_decode( p[1] )) > 63) return FALSE;
 
         buf[i + 0] = (c1 << 6) | c0;
-        buf[i + 1] = c1 >> 2;
-        buf[i + 2] = 0;
     }
     else if (len == 1)
     {
-        if ((c0 = char_decode( p[0] )) > 63) return FALSE;
-
-        buf[i + 0] = c0;
-        buf[i + 1] = 0;
-        buf[i + 2] = 0;
+        return FALSE;
     }
     return TRUE;
 }
@@ -2090,7 +2083,7 @@ BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVO
     {
     case CertCredential:
     {
-        char hash[CERT_HASH_LENGTH + 2];
+        char hash[CERT_HASH_LENGTH];
         CERT_CREDENTIAL_INFO *cert;
 
         if (len != 27 || !cred_decode( cred + 3, len, hash ))
@@ -2108,7 +2101,7 @@ BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVO
     case UsernameTargetCredential:
     {
         USERNAME_TARGET_CREDENTIAL_INFO *target;
-        ULONGLONG size = 0;
+        DWORD size;
 
         if (len < 9 || !cred_decode( cred + 3, 6, (char *)&size ) ||
             !size || size % sizeof(WCHAR) || size > INT_MAX)
@@ -2157,7 +2150,7 @@ BOOL WINAPI CredIsMarshaledCredentialW(LPCWSTR name)
 
     if (name && name[0] == '@' && name[1] == '@' && name[2] > 'A' && name[3])
     {
-        char hash[CERT_HASH_LENGTH + 2];
+        char hash[CERT_HASH_LENGTH];
         int len = strlenW(name + 3 );
         DWORD size;
 
-- 
1.8.3.2



More information about the wine-patches mailing list