Author: ion Date: Sat Feb 18 23:59:31 2012 New Revision: 55688
URL: http://svn.reactos.org/svn/reactos?rev=55688&view=rev Log: [NTOSKRNL]: Implement SeCheckPrivilegedObject and call it in the two cases where it's needed (when changing process priority) instead of spamming the debug log that we're not doing the check. [NTOSKRNL]: Implement ProcessUserModeIOPL info level (and implement Ke386SetIopl) instead of spamming we can't do this. [NTOSKRNL]: Implement ProcessExecuteOptions info level (and implement MmSetExecuteOptions) instead of spamming we can't do this. [NDK]: Add NoExecute Flags based on ProcessHacker. No longer spammed to death for every process all the time.
Modified: trunk/reactos/include/ndk/mmtypes.h trunk/reactos/ntoskrnl/include/internal/ke.h trunk/reactos/ntoskrnl/include/internal/mm.h trunk/reactos/ntoskrnl/include/internal/se.h trunk/reactos/ntoskrnl/ke/i386/v86vdm.c trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c trunk/reactos/ntoskrnl/ps/query.c trunk/reactos/ntoskrnl/se/priv.c
Modified: trunk/reactos/include/ndk/mmtypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/mmtypes.h?rev=5... ============================================================================== --- trunk/reactos/include/ndk/mmtypes.h [iso-8859-1] (original) +++ trunk/reactos/include/ndk/mmtypes.h [iso-8859-1] Sat Feb 18 23:59:31 2012 @@ -63,8 +63,18 @@ #define MAP_PROCESS 1 #define MAP_SYSTEM 2
+// +// Flags for ProcessExecutionOptions +// +#define MEM_EXECUTE_OPTION_DISABLE 0x1 +#define MEM_EXECUTE_OPTION_ENABLE 0x2 +#define MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION 0x4 +#define MEM_EXECUTE_OPTION_PERMANENT 0x8 +#define MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE 0x10 +#define MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE 0x20 +#define MEM_EXECUTE_OPTION_VALID_FLAGS 0x3F + #ifndef NTOS_MODE_USER - // // Virtual Memory Flags //
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/k... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Sat Feb 18 23:59:31 2012 @@ -729,6 +729,10 @@
VOID NTAPI +Ke386SetIOPL(VOID); + +VOID +NTAPI KiCheckForKernelApcDelivery(VOID);
LONG
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/m... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] Sat Feb 18 23:59:31 2012 @@ -1503,6 +1503,10 @@ NTAPI MmReleaseMmInfo(struct _EPROCESS *Process);
+NTSTATUS +NTAPI +MmSetExecuteOptions(IN ULONG ExecuteOptions); + VOID NTAPI MmDeleteProcessPageDirectory(struct _EPROCESS *Process);
Modified: trunk/reactos/ntoskrnl/include/internal/se.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/s... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/se.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/se.h [iso-8859-1] Sat Feb 18 23:59:31 2012 @@ -226,6 +226,15 @@ KPROCESSOR_MODE PreviousMode );
+BOOLEAN +NTAPI +SeCheckPrivilegedObject( + IN LUID PrivilegeValue, + IN HANDLE ObjectHandle, + IN ACCESS_MASK DesiredAccess, + IN KPROCESSOR_MODE PreviousMode +); + NTSTATUS NTAPI SepDuplicateToken(
Modified: trunk/reactos/ntoskrnl/ke/i386/v86vdm.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/v86vdm.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/v86vdm.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/i386/v86vdm.c [iso-8859-1] Sat Feb 18 23:59:31 2012 @@ -563,6 +563,34 @@ /* Exit to V86 mode */ KiEoiHelper(TrapFrame); } + +VOID +NTAPI +Ke386SetIOPL(VOID) +{ + + PKTHREAD Thread = KeGetCurrentThread(); + PKPROCESS Process = Thread->ApcState.Process; + PKTRAP_FRAME TrapFrame; + CONTEXT Context; + + /* IOPL was enabled for this process/thread */ + Process->Iopl = TRUE; + Thread->Iopl = TRUE; + + /* Get the trap frame on exit */ + TrapFrame = KeGetTrapFrame(Thread); + + /* Convert to a context */ + Context.ContextFlags = CONTEXT_CONTROL; + KeTrapFrameToContext(TrapFrame, NULL, &Context); + + /* Set the IOPL flag */ + Context.EFlags |= EFLAGS_IOPL; + + /* Convert back to a trap frame */ + KeContextToTrapFrame(&Context, NULL, TrapFrame, CONTEXT_CONTROL, UserMode); +}
/* PUBLIC FUNCTIONS ***********************************************************/
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Sat Feb 18 23:59:31 2012 @@ -1094,4 +1094,73 @@ return Status; }
+NTSTATUS +NTAPI +MmSetExecuteOptions(IN ULONG ExecuteOptions) +{ + + PKPROCESS CurrentProcess = &PsGetCurrentProcess()->Pcb; + KLOCK_QUEUE_HANDLE ProcessLock; + NTSTATUS Status = STATUS_ACCESS_DENIED; + ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); + + /* Only accept valid flags */ + if (ExecuteOptions & ~MEM_EXECUTE_OPTION_VALID_FLAGS) + { + /* Fail */ + DPRINT1("Invalid no-execute options\n"); + return STATUS_INVALID_PARAMETER; + } + + /* Change the NX state in the process lock */ + KiAcquireProcessLock(CurrentProcess, &ProcessLock); + + /* Don't change anything if the permanent flag was set */ + if (!CurrentProcess->Flags.Permanent) + { + /* Start by assuming it's not disabled */ + CurrentProcess->Flags.ExecuteDisable = FALSE; + + /* Now process each flag and turn the equivalent bit on */ + if (ExecuteOptions & MEM_EXECUTE_OPTION_DISABLE) + { + CurrentProcess->Flags.ExecuteDisable = TRUE; + } + if (ExecuteOptions & MEM_EXECUTE_OPTION_ENABLE) + { + CurrentProcess->Flags.ExecuteEnable = TRUE; + } + if (ExecuteOptions & MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION) + { + CurrentProcess->Flags.DisableThunkEmulation = TRUE; + } + if (ExecuteOptions & MEM_EXECUTE_OPTION_PERMANENT) + { + CurrentProcess->Flags.Permanent = TRUE; + } + if (ExecuteOptions & MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE) + { + CurrentProcess->Flags.ExecuteDispatchEnable = TRUE; + } + if (ExecuteOptions & MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE) + { + CurrentProcess->Flags.ImageDispatchEnable = TRUE; + } + + /* These are turned on by default if no-execution is also eanbled */ + if (CurrentProcess->Flags.ExecuteEnable) + { + CurrentProcess->Flags.ExecuteDispatchEnable = TRUE; + CurrentProcess->Flags.ImageDispatchEnable = TRUE; + } + + /* All good */ + Status = STATUS_SUCCESS; + } + + /* Release the lock and return status */ + KiReleaseProcessLock(&ProcessLock); + return Status; +} + /* EOF */
Modified: trunk/reactos/ntoskrnl/ps/query.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/query.c?rev=556... ============================================================================== --- trunk/reactos/ntoskrnl/ps/query.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ps/query.c [iso-8859-1] Sat Feb 18 23:59:31 2012 @@ -928,6 +928,8 @@ KAFFINITY ValidAffinity, Affinity = 0; ULONG DefaultHardErrorMode = 0, BasePriority = 0, MemoryPriority = 0; ULONG DisableBoost = 0, DebugFlags = 0, EnableFixup = 0, Boost = 0; + ULONG NoExecute = 0; + BOOLEAN HasPrivilege; PLIST_ENTRY Next; PETHREAD Thread; PAGED_CODE(); @@ -1189,8 +1191,17 @@ if ((PriorityClass.PriorityClass != Process->PriorityClass) && (PriorityClass.PriorityClass == PROCESS_PRIORITY_CLASS_REALTIME)) { - /* TODO: Check privileges */ - DPRINT1("Should check privilege\n"); + /* Check the privilege */ + HasPrivilege = SeCheckPrivilegedObject(SeIncreaseBasePriorityPrivilege, + ProcessHandle, + PROCESS_SET_INFORMATION, + PreviousMode); + if (!HasPrivilege) + { + ObDereferenceObject(Process); + DPRINT1("Privilege to change priority to realtime lacking\n"); + return STATUS_PRIVILEGE_NOT_HELD; + } }
/* Check if we have a job */ @@ -1284,7 +1295,16 @@ /* Check if the new base is higher */ if (BasePriority > Process->Pcb.BasePriority) { - DPRINT1("Should check privilege\n"); + HasPrivilege = SeCheckPrivilegedObject(SeIncreaseBasePriorityPrivilege, + ProcessHandle, + PROCESS_SET_INFORMATION, + PreviousMode); + if (!HasPrivilege) + { + ObDereferenceObject(Process); + DPRINT1("Privilege to change priority from %lx to %lx lacking\n", BasePriority, Process->Pcb.BasePriority); + return STATUS_PRIVILEGE_NOT_HELD; + } }
/* Call Ke */ @@ -1595,12 +1615,61 @@ KeSetAutoAlignmentProcess(&Process->Pcb, FALSE); Status = STATUS_SUCCESS; break; - + + case ProcessUserModeIOPL: + + /* Only TCB can do this */ + if (!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) + { + /* Fail */ + DPRINT1("Need TCB to set IOPL\n"); + Status = STATUS_PRIVILEGE_NOT_HELD; + break; + } + + /* Only supported on x86 */ +#if defined (_X86_) + Ke386SetIOPL(); +#endif + /* Done */ + break; + + case ProcessExecuteFlags: + + /* Check buffer length */ + if (ProcessInformationLength != sizeof(ULONG)) + { + Status = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + if (ProcessHandle != NtCurrentProcess()) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + /* Enter SEH for direct buffer read */ + _SEH2_TRY + { + NoExecute = *(PULONG)ProcessInformation; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Get exception code */ + Status = _SEH2_GetExceptionCode(); + _SEH2_YIELD(break); + } + _SEH2_END; + + /* Call Mm for the update */ + Status = MmSetExecuteOptions(NoExecute); + break; + /* We currently don't implement any of these */ case ProcessLdtInformation: case ProcessLdtSize: case ProcessIoPortHandlers: - case ProcessUserModeIOPL: case ProcessWx86Information: DPRINT1("VDM/16-bit Request not implemented: %lx\n", ProcessInformationClass); Status = STATUS_NOT_IMPLEMENTED; @@ -1623,11 +1692,6 @@
case ProcessHandleTracing: DPRINT1("Handle tracing not implemented\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - - case ProcessExecuteFlags: - DPRINT1("No execute support not implemented\n"); Status = STATUS_NOT_IMPLEMENTED; break;
Modified: trunk/reactos/ntoskrnl/se/priv.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/priv.c?rev=5568... ============================================================================== --- trunk/reactos/ntoskrnl/se/priv.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/se/priv.c [iso-8859-1] Sat Feb 18 23:59:31 2012 @@ -426,6 +426,44 @@ return Result; }
+BOOLEAN +NTAPI +SeCheckPrivilegedObject(IN LUID PrivilegeValue, + IN HANDLE ObjectHandle, + IN ACCESS_MASK DesiredAccess, + IN KPROCESSOR_MODE PreviousMode) +{ + SECURITY_SUBJECT_CONTEXT SubjectContext; + PRIVILEGE_SET Priv; + BOOLEAN Result; + + PAGED_CODE(); + + SeCaptureSubjectContext(&SubjectContext); + + Priv.PrivilegeCount = 1; + Priv.Control = PRIVILEGE_SET_ALL_NECESSARY; + Priv.Privilege[0].Luid = PrivilegeValue; + Priv.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED; + + Result = SePrivilegeCheck(&Priv, &SubjectContext, PreviousMode); + if (PreviousMode != KernelMode) + { +#if 0 + SePrivilegeObjectAuditAlarm(ObjectHandle, + &SubjectContext, + DesiredAccess, + &PrivilegeValue, + Result, + PreviousMode); +#endif + } + + SeReleaseSubjectContext(&SubjectContext); + + return Result; +} + /* SYSTEM CALLS ***************************************************************/
NTSTATUS