Module: wine Branch: master Commit: bff64e8578d54fa27ee9667d70812c72b8db4d1e URL: http://source.winehq.org/git/wine.git/?a=commit;h=bff64e8578d54fa27ee9667d70...
Author: Hans Leidekker hans@codeweavers.com Date: Thu Nov 15 14:12:22 2012 +0100
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 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)