Skip to content

Commit f60be66

Browse files
committed
[MSGINA][WINLOGON] Carefully zero password memory buffers before freeing them (reactos#8172)
Including variables containing pointers to a password buffer and its lengths.
1 parent b087c08 commit f60be66

File tree

4 files changed

+57
-15
lines changed

4 files changed

+57
-15
lines changed

base/system/winlogon/sas.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,9 +541,19 @@ FreeWlxMprInfo(
541541
if (MprNotifyInfo->pszDomain)
542542
LocalFree(MprNotifyInfo->pszDomain);
543543
if (MprNotifyInfo->pszPassword)
544+
{
545+
/* Zero out the password buffer before freeing it */
546+
SIZE_T pwdLen = (wcslen(MprNotifyInfo->pszPassword) + 1) * sizeof(WCHAR);
547+
SecureZeroMemory(MprNotifyInfo->pszPassword, pwdLen);
544548
LocalFree(MprNotifyInfo->pszPassword);
549+
}
545550
if (MprNotifyInfo->pszOldPassword)
551+
{
552+
/* Zero out the password buffer before freeing it */
553+
SIZE_T pwdLen = (wcslen(MprNotifyInfo->pszOldPassword) + 1) * sizeof(WCHAR);
554+
SecureZeroMemory(MprNotifyInfo->pszOldPassword, pwdLen);
546555
LocalFree(MprNotifyInfo->pszOldPassword);
556+
}
547557
}
548558

549559
static

dll/win32/msgina/gui.c

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ DoChangePassword(
622622
MB_OK | MB_ICONEXCLAMATION,
623623
IDS_CHANGEPWDTITLE,
624624
IDS_NONMATCHINGPASSWORDS);
625-
return FALSE;
625+
goto done;
626626
}
627627

628628
/* Calculate the request buffer size */
@@ -639,7 +639,7 @@ DoChangePassword(
639639
if (RequestBuffer == NULL)
640640
{
641641
ERR("HeapAlloc failed\n");
642-
return FALSE;
642+
goto done;
643643
}
644644

645645
/* Initialize the request buffer */
@@ -729,13 +729,27 @@ DoChangePassword(
729729
(wcscmp(Domain, pgContext->DomainName) == 0) &&
730730
(wcscmp(OldPassword, pgContext->Password) == 0))
731731
{
732-
ZeroMemory(pgContext->Password, sizeof(pgContext->Password));
732+
SecureZeroMemory(pgContext->Password, sizeof(pgContext->Password));
733733
wcscpy(pgContext->Password, NewPassword1);
734734
}
735735

736736
done:
737+
/* Zero out the password buffers */
738+
SecureZeroMemory(&OldPassword, sizeof(OldPassword));
739+
SecureZeroMemory(&NewPassword1, sizeof(NewPassword1));
740+
SecureZeroMemory(&NewPassword2, sizeof(NewPassword2));
741+
737742
if (RequestBuffer != NULL)
743+
{
744+
/* Zero out the password buffers before freeing them */
745+
SecureZeroMemory(RequestBuffer->OldPassword.Buffer,
746+
RequestBuffer->OldPassword.MaximumLength);
747+
SecureZeroMemory(&RequestBuffer->OldPassword, sizeof(RequestBuffer->OldPassword));
748+
SecureZeroMemory(RequestBuffer->NewPassword.Buffer,
749+
RequestBuffer->NewPassword.MaximumLength);
750+
SecureZeroMemory(&RequestBuffer->NewPassword, sizeof(RequestBuffer->NewPassword));
738751
HeapFree(GetProcessHeap(), 0, RequestBuffer);
752+
}
739753

740754
if (ResponseBuffer != NULL)
741755
LsaFreeReturnBuffer(ResponseBuffer);
@@ -1143,20 +1157,23 @@ DoLogon(
11431157
(SubStatus == STATUS_PASSWORD_EXPIRED))
11441158
{
11451159
if (SubStatus == STATUS_PASSWORD_MUST_CHANGE)
1160+
{
11461161
ResourceMessageBox(pgContext,
11471162
hwndDlg,
11481163
MB_OK | MB_ICONSTOP,
11491164
IDS_LOGONTITLE,
11501165
IDS_PASSWORDMUSTCHANGE);
1166+
}
11511167
else
1168+
{
11521169
ResourceMessageBox(pgContext,
11531170
hwndDlg,
11541171
MB_OK | MB_ICONSTOP,
11551172
IDS_LOGONTITLE,
11561173
IDS_PASSWORDEXPIRED);
1174+
}
11571175

1158-
if (!OnChangePassword(hwndDlg,
1159-
pgContext))
1176+
if (!OnChangePassword(hwndDlg, pgContext))
11601177
goto done;
11611178

11621179
Status = DoLoginTasks(pgContext,
@@ -1167,7 +1184,6 @@ DoLogon(
11671184
if (!NT_SUCCESS(Status))
11681185
{
11691186
TRACE("Login after password change failed! (Status 0x%08lx)\n", Status);
1170-
11711187
goto done;
11721188
}
11731189
}
@@ -1220,7 +1236,7 @@ DoLogon(
12201236
goto done;
12211237
}
12221238

1223-
ZeroMemory(pgContext->Password, sizeof(pgContext->Password));
1239+
SecureZeroMemory(pgContext->Password, sizeof(pgContext->Password));
12241240
wcscpy(pgContext->Password, Password);
12251241

12261242
result = TRUE;
@@ -1232,7 +1248,12 @@ DoLogon(
12321248
HeapFree(GetProcessHeap(), 0, UserName);
12331249

12341250
if (Password != NULL)
1251+
{
1252+
/* Zero out the password buffer before freeing it */
1253+
SIZE_T pwdLen = (wcslen(Password) + 1) * sizeof(WCHAR);
1254+
SecureZeroMemory(Password, pwdLen);
12351255
HeapFree(GetProcessHeap(), 0, Password);
1256+
}
12361257

12371258
if (Domain != NULL)
12381259
HeapFree(GetProcessHeap(), 0, Domain);
@@ -1542,7 +1563,12 @@ DoUnlock(
15421563
HeapFree(GetProcessHeap(), 0, UserName);
15431564

15441565
if (Password != NULL)
1566+
{
1567+
/* Zero out the password buffer before freeing it */
1568+
SIZE_T pwdLen = (wcslen(Password) + 1) * sizeof(WCHAR);
1569+
SecureZeroMemory(Password, pwdLen);
15451570
HeapFree(GetProcessHeap(), 0, Password);
1571+
}
15461572

15471573
return res;
15481574
}

dll/win32/msgina/lsa.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,23 @@ MyLogonUser(
130130
AuthInfo->UserName.MaximumLength = UserName.MaximumLength;
131131
AuthInfo->UserName.Buffer = (PWCHAR)Ptr;
132132
if (UserName.MaximumLength > 0)
133+
{
133134
RtlCopyMemory(AuthInfo->UserName.Buffer,
134135
UserName.Buffer,
135136
UserName.MaximumLength);
137+
}
136138

137139
Ptr += UserName.MaximumLength;
138140

139141
AuthInfo->Password.Length = Password.Length;
140142
AuthInfo->Password.MaximumLength = Password.MaximumLength;
141143
AuthInfo->Password.Buffer = (PWCHAR)Ptr;
142144
if (Password.MaximumLength > 0)
145+
{
143146
RtlCopyMemory(AuthInfo->Password.Buffer,
144147
Password.Buffer,
145148
Password.MaximumLength);
149+
}
146150

147151
/* Create the Logon SID*/
148152
AllocateLocallyUniqueId(&LogonId);
@@ -232,21 +236,18 @@ MyLogonUser(
232236
TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart);
233237

234238
if (TokenHandle != NULL)
235-
{
236239
TRACE("TokenHandle: %p\n", TokenHandle);
237-
}
238240

239241
*phToken = TokenHandle;
240242

241243
done:
244+
SecureZeroMemory(&Password, sizeof(Password));
245+
242246
if (ProfileBuffer != NULL)
243247
LsaFreeReturnBuffer(ProfileBuffer);
244248

245-
if (!NT_SUCCESS(Status))
246-
{
247-
if (TokenHandle != NULL)
248-
CloseHandle(TokenHandle);
249-
}
249+
if (!NT_SUCCESS(Status) && (TokenHandle != NULL))
250+
CloseHandle(TokenHandle);
250251

251252
if (TokenGroups != NULL)
252253
RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups);
@@ -258,7 +259,12 @@ MyLogonUser(
258259
RtlFreeSid(LogonSid);
259260

260261
if (AuthInfo != NULL)
262+
{
263+
/* Zero out the password buffers before freeing */
264+
SecureZeroMemory(AuthInfo->Password.Buffer, AuthInfo->Password.MaximumLength);
265+
SecureZeroMemory(&AuthInfo->Password, sizeof(AuthInfo->Password));
261266
RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo);
267+
}
262268

263269
return Status;
264270
}

dll/win32/msgina/msgina.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1071,7 +1071,7 @@ WlxLogoff(
10711071
TRACE("WlxLogoff(%p)\n", pWlxContext);
10721072

10731073
/* Delete the password */
1074-
ZeroMemory(pgContext->Password, sizeof(pgContext->Password));
1074+
SecureZeroMemory(pgContext->Password, sizeof(pgContext->Password));
10751075

10761076
/* Close the user token */
10771077
CloseHandle(pgContext->UserToken);

0 commit comments

Comments
 (0)