[NTOS]: Fix Implementation of BreakOnTermination -- Process Flags should be accessed with interlocked bit semantics, not through C bitfield extension.

[NTOS]: Revert 47425 and apply a better fix.

svn path=/trunk/; revision=47426
This commit is contained in:
Sir Richard 2010-05-29 19:21:08 +00:00
parent c5cc4a4bd7
commit 27957c2212

View file

@ -753,8 +753,7 @@ NtQueryInformationProcess(IN HANDLE ProcessHandle,
PreviousMode, PreviousMode,
(PVOID*)&Process, (PVOID*)&Process,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status)) break;
break;
/* Enter SEH for writing back data */ /* Enter SEH for writing back data */
_SEH2_TRY _SEH2_TRY
@ -869,6 +868,7 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
PROCESS_SESSION_INFORMATION SessionInfo = {0}; PROCESS_SESSION_INFORMATION SessionInfo = {0};
PROCESS_PRIORITY_CLASS PriorityClass = {0}; PROCESS_PRIORITY_CLASS PriorityClass = {0};
PVOID ExceptionPort; PVOID ExceptionPort;
ULONG Break;
PAGED_CODE(); PAGED_CODE();
/* Verify Information Class validity */ /* Verify Information Class validity */
@ -927,11 +927,10 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
{ {
/* Get the exception code */ /* Get the exception code */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
} }
_SEH2_END; _SEH2_END;
if (!NT_SUCCESS(Status)) break;
/* Get the LPC Port */ /* Get the LPC Port */
Status = ObReferenceObjectByHandle(PortHandle, Status = ObReferenceObjectByHandle(PortHandle,
0, 0,
@ -973,11 +972,10 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
{ {
/* Get the exception code */ /* Get the exception code */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
} }
_SEH2_END; _SEH2_END;
if (!NT_SUCCESS(Status)) break;
/* Assign the actual token */ /* Assign the actual token */
Status = PspSetPrimaryToken(Process, TokenHandle, NULL); Status = PspSetPrimaryToken(Process, TokenHandle, NULL);
break; break;
@ -1027,11 +1025,10 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
{ {
/* Get the exception code */ /* Get the exception code */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
} }
_SEH2_END; _SEH2_END;
if (!NT_SUCCESS(Status)) break;
/* Setting the session id requires the SeTcbPrivilege */ /* Setting the session id requires the SeTcbPrivilege */
if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode))
{ {
@ -1096,11 +1093,10 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
{ {
/* Return the exception code */ /* Return the exception code */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
} }
_SEH2_END; _SEH2_END;
if (!NT_SUCCESS(Status)) break;
/* Check for invalid PriorityClass value */ /* Check for invalid PriorityClass value */
if (PriorityClass.PriorityClass > PROCESS_PRIORITY_CLASS_ABOVE_NORMAL) if (PriorityClass.PriorityClass > PROCESS_PRIORITY_CLASS_ABOVE_NORMAL)
{ {
@ -1201,6 +1197,20 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
break; break;
} }
/* Enter SEH for direct buffer read */
_SEH2_TRY
{
Break = *(PULONG)ProcessInformation;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Get exception code */
Break = 0;
Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
}
_SEH2_END;
/* Setting 'break on termination' requires the SeDebugPrivilege */ /* Setting 'break on termination' requires the SeDebugPrivilege */
if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode)) if (!SeSinglePrivilegeCheck(SeDebugPrivilege, PreviousMode))
{ {
@ -1208,17 +1218,16 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
break; break;
} }
/* Enter SEH for direct buffer read */ /* Set or clear the flag */
_SEH2_TRY if (Break)
{ {
Process->BreakOnTermination = *(PULONG)ProcessInformation; PspSetProcessFlag(Process, PSF_BREAK_ON_TERMINATION_BIT);
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) else
{ {
/* Get exception code */ PspClearProcessFlag(Process, PSF_BREAK_ON_TERMINATION_BIT);
Status = _SEH2_GetExceptionCode();
} }
_SEH2_END;
break; break;
/* We currently don't implement any of these */ /* We currently don't implement any of these */
@ -1328,11 +1337,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
{ {
/* Get the exception code */ /* Get the exception code */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
} }
_SEH2_END; _SEH2_END;
if (!NT_SUCCESS(Status)) break;
/* Validate it */ /* Validate it */
if ((Priority > HIGH_PRIORITY) || if ((Priority > HIGH_PRIORITY) ||
(Priority <= LOW_PRIORITY)) (Priority <= LOW_PRIORITY))
@ -1365,11 +1373,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
{ {
/* Get the exception code */ /* Get the exception code */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
} }
_SEH2_END; _SEH2_END;
if (!NT_SUCCESS(Status)) break;
/* Validate it */ /* Validate it */
if ((Priority > THREAD_BASE_PRIORITY_MAX) || if ((Priority > THREAD_BASE_PRIORITY_MAX) ||
(Priority < THREAD_BASE_PRIORITY_MIN)) (Priority < THREAD_BASE_PRIORITY_MIN))
@ -1479,11 +1486,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
{ {
/* Get the exception code */ /* Get the exception code */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
} }
_SEH2_END; _SEH2_END;
if (!NT_SUCCESS(Status)) break;
/* Assign the actual token */ /* Assign the actual token */
Status = PsAssignImpersonationToken(Thread, TokenHandle); Status = PsAssignImpersonationToken(Thread, TokenHandle);
break; break;
@ -1507,11 +1513,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
{ {
/* Get the exception code */ /* Get the exception code */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
} }
_SEH2_END; _SEH2_END;
if (!NT_SUCCESS(Status)) break;
/* Set the address */ /* Set the address */
Thread->Win32StartAddress = Address; Thread->Win32StartAddress = Address;
break; break;
@ -1535,11 +1540,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
{ {
/* Get the exception code */ /* Get the exception code */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
} }
_SEH2_END; _SEH2_END;
if (!NT_SUCCESS(Status)) break;
/* Validate it */ /* Validate it */
if (IdealProcessor > MAXIMUM_PROCESSORS) if (IdealProcessor > MAXIMUM_PROCESSORS)
{ {
@ -1584,11 +1588,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
{ {
/* Get the exception code */ /* Get the exception code */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
} }
_SEH2_END; _SEH2_END;
if (!NT_SUCCESS(Status)) break;
/* Call the kernel */ /* Call the kernel */
KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost); KeSetDisableBoostThread(&Thread->Tcb, (BOOLEAN)DisableBoost);
break; break;
@ -1612,11 +1615,10 @@ NtSetInformationThread(IN HANDLE ThreadHandle,
{ {
/* Get the exception code */ /* Get the exception code */
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
_SEH2_YIELD(break);
} }
_SEH2_END; _SEH2_END;
if (!NT_SUCCESS(Status)) break;
/* This is only valid for the current thread */ /* This is only valid for the current thread */
if (Thread != PsGetCurrentThread()) if (Thread != PsGetCurrentThread())
{ {