[NTUSER] Do assignment lock pti->spDefaultImc (#4456)

According to JIRA user simonelombardo, there was crash in exiting a thread.
- Add UserAssignmentLock, and UserAssignmentUnlock helper functions.
- Lock and unlock pti->spDefaultImc by using those helper functions.
CORE-18044
This commit is contained in:
Katayama Hirofumi MZ 2022-04-18 08:23:18 +09:00 committed by GitHub
parent 851c5e0c3a
commit 7e13883723
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 3 deletions

View file

@ -1362,9 +1362,7 @@ PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData)
else // First time. It's the default IMC.
{
// Add the first one (default) to the list.
if (pti->spDefaultImc)
UserDereferenceObject(pti->spDefaultImc);
pti->spDefaultImc = pIMC;
UserAssignmentLock((PVOID*)&pti->spDefaultImc, pIMC);
pIMC->pImcNext = NULL;
}

View file

@ -696,6 +696,7 @@ error:
VOID
UserDisplayNotifyShutdown(PPROCESSINFO ppiCurrent);
// Win: xxxDestroyThreadInfo
NTSTATUS
NTAPI
ExitThreadCallback(PETHREAD Thread)
@ -783,6 +784,7 @@ ExitThreadCallback(PETHREAD Thread)
ASSERT(FALSE);
return STATUS_UNSUCCESSFUL;
}
UserAssignmentUnlock((PVOID*)&ptiCurrent->spDefaultImc);
if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling &&
ppiCurrent->W32PF_flags & W32PF_CLASSESREGISTERED)

View file

@ -801,3 +801,39 @@ CLEANUP:
UserLeave();
END_CLEANUP;
}
// Win: HMAssignmentLock
PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew)
{
PVOID pvOld = *ppvObj;
*ppvObj = pvNew;
if (pvOld && pvOld == pvNew)
return pvOld;
if (pvNew)
UserReferenceObject(pvNew);
if (pvOld)
{
if (UserDereferenceObject(pvOld))
pvOld = NULL;
}
return pvOld;
}
// Win: HMAssignmentUnlock
PVOID FASTCALL UserAssignmentUnlock(PVOID *ppvObj)
{
PVOID pvOld = *ppvObj;
*ppvObj = NULL;
if (pvOld)
{
if (UserDereferenceObject(pvOld))
pvOld = NULL;
}
return pvOld;
}

View file

@ -20,6 +20,8 @@ void DbgUserDumpHandleTable();
PVOID FASTCALL ValidateHandle(HANDLE handle, HANDLE_TYPE type);
BOOLEAN UserDestroyObjectsForOwner(PUSER_HANDLE_TABLE Table, PVOID Owner);
BOOL FASTCALL UserMarkObjectDestroy(PVOID);
PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew);
PVOID FASTCALL UserAssignmentUnlock(PVOID *ppvObj);
static __inline VOID
UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)