diff --git a/reactos/include/ndk/pstypes.h b/reactos/include/ndk/pstypes.h index e13f47a52c0..e19da5c6e5d 100644 --- a/reactos/include/ndk/pstypes.h +++ b/reactos/include/ndk/pstypes.h @@ -780,7 +780,7 @@ typedef struct _TEB ULONG SoftPatchPtr1; ULONG SoftPatchPtr2; PVOID *TlsExpansionSlots; - ULONG ImpersionationLocale; + ULONG ImpersonationLocale; ULONG IsImpersonating; PVOID NlsCache; PVOID pShimData; diff --git a/reactos/ntoskrnl/KrnlFun.c b/reactos/ntoskrnl/KrnlFun.c index 13a43060c22..36e74460bca 100644 --- a/reactos/ntoskrnl/KrnlFun.c +++ b/reactos/ntoskrnl/KrnlFun.c @@ -30,8 +30,6 @@ // - Add security calls where necessary. // - Add tracing. // - Add failure/race checks for thread creation. -// - Complete PspSetPrimaryToken. -// - Update TEB Security information when impersonating. // // Ob: // - Possible bug in deferred deletion under Cc Rewrite branch. diff --git a/reactos/ntoskrnl/include/internal/arch/ps.h b/reactos/ntoskrnl/include/internal/arch/ps.h deleted file mode 100644 index c10edcb32aa..00000000000 --- a/reactos/ntoskrnl/include/internal/arch/ps.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __NTOSKRNL_INCLUDE_INTERNAL_ARCH_PS_H -#define __NTOSKRNL_INCLUDE_INTERNAL_ARCH_PS_H - -#ifdef _M_IX86 -#define KiArchContextSwitch KiSwapContext -#define KiArchInitThreadWithContext Ke386InitThreadWithContext -#else -#error "Unknown processor" -#endif - -#endif /* __NTOSKRNL_INCLUDE_INTERNAL_ARCH_PS_H */ - -/* EOF */ diff --git a/reactos/ntoskrnl/include/internal/ob.h b/reactos/ntoskrnl/include/internal/ob.h index 3a0215805ba..44780fd85c3 100644 --- a/reactos/ntoskrnl/include/internal/ob.h +++ b/reactos/ntoskrnl/include/internal/ob.h @@ -5,6 +5,7 @@ * PURPOSE: Internal header for the Object Manager * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ + // // Define this if you want debugging support // diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index 0eab1f124d9..6b3b4f52653 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -1,61 +1,160 @@ -#ifndef __INCLUDE_INTERNAL_PS_H -#define __INCLUDE_INTERNAL_PS_H +/* +* PROJECT: ReactOS Kernel +* LICENSE: GPL - See COPYING in the top level directory +* FILE: ntoskrnl/include/ps.h +* PURPOSE: Internal header for the Process Manager +* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) +*/ -/* Forward declarations. */ -struct _KTHREAD; -struct _KTRAPFRAME; -struct _EJOB; +// +// Define this if you want debugging support +// +#define _PS_DEBUG_ 0x00 -#include +// +// These define the Debug Masks Supported +// +#define PS_THREAD_DEBUG 0x01 +#define PS_PROCESS_DEBUG 0x02 +#define PS_SECURITY_DEBUG 0x04 +#define PS_JOB_DEBUG 0x08 +#define PS_NOTIFICATIONS_DEBUG 0x10 +#define PS_WIN32K_DEBUG 0x20 +#define PS_STATE_DEBUG 0x40 +#define PS_QUOTA_DEBUG 0x80 -/* Top level irp definitions. */ -#define FSRTL_FSP_TOP_LEVEL_IRP (0x01) -#define FSRTL_CACHE_TOP_LEVEL_IRP (0x02) -#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP (0x03) -#define FSRTL_FAST_IO_TOP_LEVEL_IRP (0x04) -#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG (0x04) +// +// Debug/Tracing support +// +#if _PS_DEBUG_ +#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented +#define PSTRACE DbgPrintEx +#else +#define PSTRACE(x, ...) \ + if (x & PspTraceLevel) DbgPrint(__VA_ARGS__) +#endif +#else +#define PSTRACE(x, ...) DPRINT(__VA_ARGS__) +#endif +// +// Maximum Count of Notification Routines +// #define PSP_MAX_CREATE_THREAD_NOTIFY 8 #define PSP_MAX_LOAD_IMAGE_NOTIFY 8 #define PSP_MAX_CREATE_PROCESS_NOTIFY 8 +// +// Maximum Job Scheduling Classes +// #define PSP_JOB_SCHEDULING_CLASSES 10 +// +// Initialization Functions +// VOID NTAPI -PspShutdownProcessManager(VOID); - -VOID -NTAPI -PsInitThreadManagment(VOID); +PspShutdownProcessManager( + VOID +); VOID INIT_FUNCTION NTAPI -PiInitProcessManager(VOID); +PsInitThreadManagment( + VOID +); VOID +INIT_FUNCTION NTAPI -PsInitProcessManagment(VOID); +PiInitProcessManager( + VOID +); VOID +INIT_FUNCTION NTAPI -PsInitIdleThread(VOID); +PsInitProcessManagment( + VOID +); -PACCESS_TOKEN -STDCALL -PsReferenceEffectiveToken( - PETHREAD Thread, - PTOKEN_TYPE TokenType, - PUCHAR b, - PSECURITY_IMPERSONATION_LEVEL Level +VOID +INIT_FUNCTION +NTAPI +PsInitIdleThread( + VOID ); NTSTATUS -STDCALL +NTAPI +PsInitializeIdleOrFirstThread( + IN PEPROCESS Process, + OUT PETHREAD* ThreadPtr, + IN PKSTART_ROUTINE StartRoutine, + IN KPROCESSOR_MODE AccessMode, + IN BOOLEAN First +); + +VOID +NTAPI +INIT_FUNCTION +PsInitJobManagment( + VOID +); + +// +// Utility Routines +// +PETHREAD +NTAPI +PsGetNextProcessThread( + IN PEPROCESS Process, + IN PETHREAD Thread OPTIONAL +); + +PEPROCESS +NTAPI +PsGetNextProcess( + IN PEPROCESS OldProcess OPTIONAL +); + +NTSTATUS +NTAPI +PspMapSystemDll( + IN PEPROCESS Process, + OUT PVOID *DllBase +); + +NTSTATUS +NTAPI +PsLocateSystemDll( + VOID +); + +NTSTATUS +NTAPI +PspGetSystemDllEntryPoints( + VOID +); + +// +// Security Routines +// +PACCESS_TOKEN +NTAPI +PsReferenceEffectiveToken( + IN PETHREAD Thread, + OUT PTOKEN_TYPE TokenType, + OUT PUCHAR b, + OUT PSECURITY_IMPERSONATION_LEVEL Level +); + +NTSTATUS +NTAPI PsOpenTokenOfProcess( - HANDLE ProcessHandle, - PACCESS_TOKEN* Token + IN HANDLE ProcessHandle, + OUT PACCESS_TOKEN* Token ); NTSTATUS @@ -66,15 +165,30 @@ PspSetPrimaryToken( IN PTOKEN Token OPTIONAL ); -PETHREAD +NTSTATUS NTAPI -PsGetNextProcessThread( +PspInitializeProcessSecurity( IN PEPROCESS Process, - IN PETHREAD Thread OPTIONAL + IN PEPROCESS Parent OPTIONAL ); VOID -STDCALL +NTAPI +PspDeleteProcessSecurity( + IN PEPROCESS Process +); + +VOID +NTAPI +PspDeleteThreadSecurity( + IN PETHREAD Thread +); + +// +// Reaping and Deletion +// +VOID +NTAPI PsExitSpecialApc( PKAPC Apc, PKNORMAL_ROUTINE *NormalRoutine, @@ -83,97 +197,101 @@ PsExitSpecialApc( PVOID *SystemArgument2 ); -NTSTATUS -STDCALL -PspInitializeProcessSecurity( - PEPROCESS Process, - PEPROCESS Parent OPTIONAL +VOID +NTAPI +PspReapRoutine( + IN PVOID Context ); VOID -STDCALL +NTAPI +PspExitThread( + IN NTSTATUS ExitStatus +); + +NTSTATUS +NTAPI +PspTerminateThreadByPointer( + IN PETHREAD Thread, + IN NTSTATUS ExitStatus, + IN BOOLEAN bSelf +); + +VOID +NTAPI +PspExitProcess( + IN BOOLEAN LastThread, + IN PEPROCESS Process +); + +VOID +NTAPI +PspDeleteProcess( + IN PVOID ObjectBody +); + +VOID +NTAPI +PspDeleteThread( + IN PVOID ObjectBody +); + +// +// Thread/Process Startup +// +VOID +NTAPI PspSystemThreadStartup( PKSTART_ROUTINE StartRoutine, PVOID StartContext ); -NTSTATUS -NTAPI -PsInitializeIdleOrFirstThread( - PEPROCESS Process, - PETHREAD* ThreadPtr, - PKSTART_ROUTINE StartRoutine, - KPROCESSOR_MODE AccessMode, - BOOLEAN First -); - -VOID -STDCALL -PspReapRoutine(PVOID Context); - -VOID -STDCALL -PspExitThread(NTSTATUS ExitStatus); - -NTSTATUS -STDCALL -PspTerminateThreadByPointer( - PETHREAD Thread, - NTSTATUS ExitStatus, - BOOLEAN bSelf -); - -PEPROCESS -STDCALL -PsGetNextProcess(PEPROCESS OldProcess); - -VOID -STDCALL -PsIdleThreadMain(PVOID Context); - -VOID -STDCALL -PspExitProcess(BOOLEAN LastThread, - PEPROCESS Process); - -VOID -STDCALL -PspDeleteProcess(PVOID ObjectBody); - -VOID -STDCALL -PspDeleteThread(PVOID ObjectBody); - VOID NTAPI -INIT_FUNCTION -PsInitJobManagment(VOID); +PsIdleThreadMain( + IN PVOID Context +); +// +// Quota Support +// VOID -STDCALL +NTAPI PspInheritQuota( - PEPROCESS Process, - PEPROCESS ParentProcess + IN PEPROCESS Process, + IN PEPROCESS ParentProcess ); VOID -STDCALL -PspDestroyQuotaBlock(PEPROCESS Process); +NTAPI +PspDestroyQuotaBlock( + IN PEPROCESS Process +); +// +// VDM Support +// NTSTATUS -STDCALL -PspMapSystemDll( - PEPROCESS Process, - PVOID *DllBase +NTAPI +PspDeleteLdt( + IN PEPROCESS Process ); NTSTATUS -STDCALL -PsLocateSystemDll(VOID); +NTAPI +PspDeleteVdmObjects( + IN PEPROCESS Process +); -NTSTATUS -STDCALL -PspGetSystemDllEntryPoints(VOID); +// +// Job Routines +// +VOID +NTAPI +PspExitProcessFromJob( + IN PEJOB Job, + IN PEPROCESS Process +); VOID NTAPI @@ -182,29 +300,10 @@ PspRemoveProcessFromJob( IN PEJOB Job ); -NTSTATUS -NTAPI -PspDeleteLdt(IN PEPROCESS Process); - -NTSTATUS -NTAPI -PspDeleteVdmObjects(IN PEPROCESS Process); - -VOID -NTAPI -PspDeleteProcessSecurity(IN PEPROCESS Process); - -VOID -NTAPI -PspDeleteThreadSecurity(IN PETHREAD Thread); - -VOID -NTAPI -PspExitProcessFromJob( - IN PEJOB Job, - IN PEPROCESS Process -); - +// +// Global data inside the Process Manager +// +extern ULONG PspTraceLevel; extern LCID PsDefaultThreadLocaleId; extern LCID PsDefaultSystemLocaleId; extern LIST_ENTRY PspReaperListHead; @@ -231,6 +330,8 @@ extern PVOID PspSystemDllEntryPoint; extern PVOID PspSystemDllBase; extern BOOLEAN PspUseJobSchedulingClasses; extern CHAR PspJobSchedulingClasses[PSP_JOB_SCHEDULING_CLASSES]; -#include "ps_x.h" -#endif /* __INCLUDE_INTERNAL_PS_H */ +// +// Inlined Functions +// +#include "ps_x.h" diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index de2a37af2d2..3ef0ebdc093 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -187,7 +187,7 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus) /* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */ DPRINT("You are : %x, swapping to: %x\n", OldThread, CurrentThread); - KiArchContextSwitch(CurrentThread); + KiSwapContext(CurrentThread); DPRINT("You are : %x, swapped from: %x\n", OldThread, CurrentThread); return; } @@ -841,11 +841,11 @@ KeInitThread(IN OUT PKTHREAD Thread, _SEH_TRY { /* Initalize the Thread Context */ - KiArchInitThreadWithContext(Thread, - SystemRoutine, - StartRoutine, - StartContext, - Context); + Ke386InitThreadWithContext(Thread, + SystemRoutine, + StartRoutine, + StartContext, + Context); } _SEH_HANDLE { diff --git a/reactos/ntoskrnl/ps/security.c b/reactos/ntoskrnl/ps/security.c index 35a46f2cdc6..aa2e7e72ae3 100644 --- a/reactos/ntoskrnl/ps/security.c +++ b/reactos/ntoskrnl/ps/security.c @@ -97,6 +97,75 @@ PspInitializeProcessSecurity(IN PEPROCESS Process, return Status; } +NTSTATUS +NTAPI +PspWriteTebImpersonationInfo(IN PETHREAD Thread, + IN PETHREAD CurrentThread) +{ + PEPROCESS Process; + PTEB Teb; + BOOLEAN Attached = FALSE; + BOOLEAN IsImpersonating; + KAPC_STATE ApcState; + PAGED_CODE(); + + /* Sanity check */ + ASSERT(CurrentThread == PsGetCurrentThread()); + + /* Get process and TEB */ + Process = Thread->ThreadsProcess; + Teb = Thread->Tcb.Teb; + if (Teb) + { + /* Check if we're not in the right process */ + if (Thread->Tcb.ApcState.Process != &Process->Pcb) + { + /* Attach to the process */ + KeStackAttachProcess(&Process->Pcb, &ApcState); + Attached = TRUE; + } + + /* Check if we're in a different thread */ + if (Thread != CurrentThread) + { + /* Acquire thread rundown protection */ + ExAcquireRundownProtection(&Thread->RundownProtect); + } + + /* Check if the thread is impersonating */ + IsImpersonating = Thread->ActiveImpersonationInfo; + if (IsImpersonating) + { + /* Set TEB data */ + Teb->ImpersonationLocale = -1; + Teb->IsImpersonating = 1; + } + else + { + /* Set TEB data */ + Teb->ImpersonationLocale = 0; + Teb->IsImpersonating = 0; + } + + /* Set new flag */ + Thread->ActiveImpersonationInfo = TRUE; + + /* Check if we're in a different thread */ + if (Thread != CurrentThread) + { + /* Release protection */ + ExReleaseRundownProtection(&Thread->RundownProtect); + } + + /* Dettach */ + if (Attached) KeUnstackDetachProcess(&ApcState); + } + + /* Return to caller */ + return STATUS_SUCCESS; +} + + NTSTATUS NTAPI PspAssignPrimaryToken(IN PEPROCESS Process, @@ -129,7 +198,10 @@ PspSetPrimaryToken(IN PEPROCESS Process, { KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); BOOLEAN IsChild; - NTSTATUS Status; + NTSTATUS Status, AccessStatus; + BOOLEAN Result, SdAllocated; + PSECURITY_DESCRIPTOR SecurityDescriptor; + SECURITY_SUBJECT_CONTEXT SubjectContext; /* Make sure we got a handle */ if (TokenHandle) @@ -171,14 +243,42 @@ PspSetPrimaryToken(IN PEPROCESS Process, if (NT_SUCCESS(Status)) { /* - * The idea here is that we need to completely reverify - * if the process still has access to itself under this new - * token, by doing an SeAccessCheck with the Primary Token and - * the SD of the Process (ObGetObjectSecurity). - * In the really twisted case where we lose access to ourselves, - * we would set Process->GrantedAccess to 0. + * We need to completely reverify if the process still has access to + * itself under this new token. */ - DPRINT1("Process security not complete\n"); + Status = ObGetObjectSecurity(Process, + &SecurityDescriptor, + &SdAllocated); + if (NT_SUCCESS(Status)) + { + /* Setup the security context */ + SubjectContext.ProcessAuditId = Process; + SubjectContext.PrimaryToken = PsReferencePrimaryToken(Process); + SubjectContext.ClientToken = NULL; + + /* Do the access check */ + Result = SeAccessCheck(SecurityDescriptor, + &SubjectContext, + FALSE, + MAXIMUM_ALLOWED, + 0, + NULL, + &PsProcessType->TypeInfo.GenericMapping, + PreviousMode, + &Process->GrantedAccess, + &AccessStatus); + + /* Dereference the token and let go the SD */ + ObFastDereferenceObject(&Process->Token, + SubjectContext.PrimaryToken); + ObReleaseObjectSecurity(SecurityDescriptor, SdAllocated); + + /* Remove access if it failed */ + if (!Result) Process->GrantedAccess = 0; + } + + /* Dereference the process */ + ObDereferenceObject(Process); } /* Dereference the token */ @@ -437,6 +537,9 @@ PsRevertThreadToSelf(IN PETHREAD Thread) /* Dereference the impersonation token */ if (Token) ObDereferenceObject(Token); + + /* Write impersonation info to the TEB */ + PspWriteTebImpersonationInfo(Thread, PsGetCurrentThread()); } /* @@ -529,8 +632,10 @@ PsImpersonateClient(IN PETHREAD Thread, PspUnlockThreadSecurityExclusive(Thread); } + /* Write impersonation info to the TEB */ + PspWriteTebImpersonationInfo(Thread, PsGetCurrentThread()); + /* Dereference the token and return success */ - ObReferenceObject(Token); if (OldToken) ObDereferenceObject(OldToken); return STATUS_SUCCESS; }