From bff64e8578d54fa27ee9667d70812c72b8db4d1e Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Thu, 15 Nov 2012 14:12:22 +0100 Subject: [PATCH] advapi32: Avoid a buffer overflow in CredUnmarshalCredentialW. 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 b2597b63826..b7358211071 100644 --- a/dlls/advapi32/cred.c +++ b/dlls/advapi32/cred.c @@ -20,6 +20,7 @@ #include #include +#include #ifdef __APPLE__ # include @@ -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 3d37a3cfee8..83212c53966 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)