advapi32: Avoid a buffer overflow in CredUnmarshalCredentialW.

Spotted by Stefan Leichter.
This commit is contained in:
Hans Leidekker 2012-11-15 14:12:22 +01:00 committed by Alexandre Julliard
parent 6395af1ae7
commit bff64e8578
2 changed files with 13 additions and 2 deletions

View File

@ -20,6 +20,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <time.h> #include <time.h>
#include <limits.h>
#ifdef __APPLE__ #ifdef __APPLE__
# include <Security/SecKeychain.h> # 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 ) 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); 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: case UsernameTargetCredential:
{ {
USERNAME_TARGET_CREDENTIAL_INFO *target; 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 ); SetLastError( ERROR_INVALID_PARAMETER );
return FALSE; return FALSE;

View File

@ -670,6 +670,14 @@ static void test_CredUnmarshalCredentialA(void)
ok( username->UserName != NULL, "UserName is NULL\n" ); ok( username->UserName != NULL, "UserName is NULL\n" );
ok( !lstrcmpW( username->UserName, testW ), "got %s\n", wine_dbgstr_w(username->UserName) ); ok( !lstrcmpW( username->UserName, testW ), "got %s\n", wine_dbgstr_w(username->UserName) );
pCredFree( 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) static void test_CredIsMarshaledCredentialA(void)