From b6ed8c9d936ae97f120c4e57a6d28ecdd802ea90 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Fri, 7 Feb 2025 07:33:02 +0100 Subject: [PATCH] [winpr,sspi[ fix PTH sspi_FreeAuthIdentity fix memset of password, adjust length in case PTH was used. --- winpr/libwinpr/sspi/sspi.c | 32 +++++++++++++++++++++----------- winpr/libwinpr/sspi/sspi_winpr.c | 2 +- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/winpr/libwinpr/sspi/sspi.c b/winpr/libwinpr/sspi/sspi.c index b72d21af9..a26cbc0c3 100644 --- a/winpr/libwinpr/sspi/sspi.c +++ b/winpr/libwinpr/sspi/sspi.c @@ -1114,21 +1114,31 @@ SECURITY_STATUS SEC_ENTRY sspi_VerifySignature(PCtxtHandle phContext, PSecBuffer WINPR_PRAGMA_DIAG_POP +static void zfree(WCHAR* str, size_t len, BOOL isWCHAR) +{ + if (str) + memset(str, 0, len * (isWCHAR ? sizeof(WCHAR) : sizeof(char))); + free(str); +} + void sspi_FreeAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity) { if (!identity) return; - free(identity->User); - identity->UserLength = (UINT32)0; - identity->User = NULL; - free(identity->Domain); - identity->DomainLength = (UINT32)0; - identity->Domain = NULL; + const BOOL wc = (identity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE) != 0; + zfree(identity->User, identity->UserLength, wc); + zfree(identity->Domain, identity->DomainLength, wc); - if (identity->PasswordLength > 0) - memset(identity->Password, 0, identity->PasswordLength); - free(identity->Password); - identity->Password = NULL; - identity->PasswordLength = (UINT32)0; + /* identity->PasswordLength does have a dual use. In Pass The Hash (PTH) mode the maximum + * password length (512) is added to the real length to mark this as a hash. when we free up + * this field without removing these additional bytes we would corrupt the stack. + */ + size_t len = identity->PasswordLength; + if (len > SSPI_CREDENTIALS_HASH_LENGTH_OFFSET) + len -= SSPI_CREDENTIALS_HASH_LENGTH_OFFSET; + zfree(identity->Password, len, wc); + + const SEC_WINNT_AUTH_IDENTITY empty = { 0 }; + *identity = empty; } diff --git a/winpr/libwinpr/sspi/sspi_winpr.c b/winpr/libwinpr/sspi/sspi_winpr.c index 88751eb8a..3ff1f207c 100644 --- a/winpr/libwinpr/sspi/sspi_winpr.c +++ b/winpr/libwinpr/sspi/sspi_winpr.c @@ -347,7 +347,7 @@ static BOOL copy(WCHAR** dst, ULONG* dstLen, const WCHAR* what, size_t len) return FALSE; memcpy(*dst, what, len * sizeof(WCHAR)); - *dstLen = (UINT32)len; + *dstLen = WINPR_ASSERTING_INT_CAST(UINT32, len); return TRUE; }