This commit is contained in:
Gleb Surikov 2025-03-30 09:23:29 +08:00 committed by GitHub
commit f9b657a5ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 2036 additions and 593 deletions

View file

@ -23,8 +23,8 @@
*/
HANDLE
WINAPI
CreateJobObjectA(IN LPSECURITY_ATTRIBUTES lpJobAttributes,
IN LPCSTR lpName)
CreateJobObjectA(_In_ LPSECURITY_ATTRIBUTES lpJobAttributes,
_In_ LPCSTR lpName)
{
/* Call the W(ide) function */
ConvertWin32AnsiObjectApiToUnicodeApi(JobObject, lpName, lpJobAttributes);
@ -35,8 +35,8 @@ CreateJobObjectA(IN LPSECURITY_ATTRIBUTES lpJobAttributes,
*/
HANDLE
WINAPI
CreateJobObjectW(IN LPSECURITY_ATTRIBUTES lpJobAttributes,
IN LPCWSTR lpName)
CreateJobObjectW(_In_ LPSECURITY_ATTRIBUTES lpJobAttributes,
_In_ LPCWSTR lpName)
{
/* Create the NT object */
CreateNtObjectFromWin32Api(JobObject, JobObject, JOB_OBJECT_ALL_ACCESS, lpJobAttributes, lpName);
@ -47,9 +47,9 @@ CreateJobObjectW(IN LPSECURITY_ATTRIBUTES lpJobAttributes,
*/
HANDLE
WINAPI
OpenJobObjectW(IN DWORD dwDesiredAccess,
IN BOOL bInheritHandle,
IN LPCWSTR lpName)
OpenJobObjectW(_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ LPCWSTR lpName)
{
/* Open the NT object */
OpenNtObjectFromWin32Api(JobObject, dwDesiredAccess, bInheritHandle, lpName);
@ -61,9 +61,9 @@ OpenJobObjectW(IN DWORD dwDesiredAccess,
*/
HANDLE
WINAPI
OpenJobObjectA(IN DWORD dwDesiredAccess,
IN BOOL bInheritHandle,
IN LPCSTR lpName)
OpenJobObjectA(_In_ DWORD dwDesiredAccess,
_In_ BOOL bInheritHandle,
_In_ LPCSTR lpName)
{
/* Call the W(ide) function */
ConvertOpenWin32AnsiObjectApiToUnicodeApi(JobObject, dwDesiredAccess, bInheritHandle, lpName);
@ -74,9 +74,9 @@ OpenJobObjectA(IN DWORD dwDesiredAccess,
*/
BOOL
WINAPI
IsProcessInJob(IN HANDLE ProcessHandle,
IN HANDLE JobHandle,
OUT PBOOL Result)
IsProcessInJob(_In_ HANDLE ProcessHandle,
_In_opt_ HANDLE JobHandle,
_Out_ PBOOL Result)
{
NTSTATUS Status;
@ -96,8 +96,8 @@ IsProcessInJob(IN HANDLE ProcessHandle,
*/
BOOL
WINAPI
AssignProcessToJobObject(IN HANDLE hJob,
IN HANDLE hProcess)
AssignProcessToJobObject(_In_ HANDLE hJob,
_In_ HANDLE hProcess)
{
NTSTATUS Status;
@ -116,11 +116,13 @@ AssignProcessToJobObject(IN HANDLE hJob,
*/
BOOL
WINAPI
QueryInformationJobObject(IN HANDLE hJob,
IN JOBOBJECTINFOCLASS JobObjectInformationClass,
IN LPVOID lpJobObjectInformation,
IN DWORD cbJobObjectInformationLength,
OUT LPDWORD lpReturnLength)
QueryInformationJobObject(
_In_opt_ HANDLE hJob,
_In_ JOBOBJECTINFOCLASS JobObjectInformationClass,
_Out_writes_bytes_to_(cbJobObjectInformationLength, *lpReturnLength) LPVOID
lpJobObjectInformation,
_In_ DWORD cbJobObjectInformationLength,
_Out_opt_ LPDWORD lpReturnLength)
{
NTSTATUS Status;
PVOID JobInfo;
@ -209,10 +211,11 @@ QueryInformationJobObject(IN HANDLE hJob,
*/
BOOL
WINAPI
SetInformationJobObject(IN HANDLE hJob,
IN JOBOBJECTINFOCLASS JobObjectInformationClass,
IN LPVOID lpJobObjectInformation,
IN DWORD cbJobObjectInformationLength)
SetInformationJobObject(
_In_ HANDLE hJob,
_In_ JOBOBJECTINFOCLASS JobObjectInformationClass,
_In_reads_bytes_(cbJobObjectInformationLength) LPVOID lpJobObjectInformation,
_In_ DWORD cbJobObjectInformationLength)
{
NTSTATUS Status;
PVOID JobInfo;
@ -315,8 +318,8 @@ SetInformationJobObject(IN HANDLE hJob,
*/
BOOL
WINAPI
TerminateJobObject(IN HANDLE hJob,
IN UINT uExitCode)
TerminateJobObject(_In_ HANDLE hJob,
_In_ UINT uExitCode)
{
NTSTATUS Status;

View file

@ -3814,10 +3814,11 @@ StartScan:
NULL);
}
/* Check if we're going to be debugged */
if (dwCreationFlags & DEBUG_PROCESS)
/* Check if CREATE_BREAKAWAY_FROM_JOB is set, this flag allows the child process
to break away from the job associated with the calling process */
if (dwCreationFlags & CREATE_BREAKAWAY_FROM_JOB)
{
/* Set process flag */
/* Set the corresponding process flag */
Flags |= PROCESS_CREATE_FLAGS_BREAKAWAY;
}

View file

@ -76,6 +76,27 @@
#define PSP_NON_PAGED_POOL_QUOTA_THRESHOLD 0x10000
#define PSP_PAGED_POOL_QUOTA_THRESHOLD 0x80000
//
// Flags for JobStatus in EPROCESS
//
// These are based on the layout of bit fields in the Flags2 set introduced in
// version 6.0
//
// More information:
// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ps/eprocess/flags2.htm
//
#define JOB_NOT_REALLY_ACTIVE 0x00000001
#define ACCOUNTING_FOLDED 0x00000002
//
// Job Flags
//
// More information:
// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ps/ejob/jobflags.htm
//
#define JOB_OBJECT_CLOSE_DONE 0x00000001
#define JOB_OBJECT_TERMINATING 0x00000080
//
// Thread "Set/Get Context" Context Structure
//
@ -371,18 +392,40 @@ PspQueryDescriptorThread(
//
// Job Routines
//
typedef NTSTATUS
(*PJOB_ENUMERATOR_CALLBACK)(
_In_ PEPROCESS Process,
_In_opt_ PVOID Context
);
NTSTATUS
NTAPI
PspEnumerateProcessesInJob(
_In_ PEJOB Job,
_In_ PJOB_ENUMERATOR_CALLBACK Callback,
_In_opt_ PVOID Context,
_In_ BOOLEAN BreakOnCallbackFailure
);
NTSTATUS
NTAPI
PspAssignProcessToJob(
_In_ PEPROCESS Process,
_In_ PEJOB Job
);
VOID
NTAPI
PspExitProcessFromJob(
IN PEJOB Job,
IN PEPROCESS Process
_In_ PEJOB Job,
_In_ PEPROCESS Process
);
VOID
NTAPI
PspRemoveProcessFromJob(
IN PEPROCESS Process,
IN PEJOB Job
_In_ PEPROCESS Process,
_In_ PEJOB Job
);
CODE_SEG("INIT")
@ -392,10 +435,20 @@ PspInitializeJobStructures(
VOID
);
VOID
NTAPI
PspCloseJob(
_In_ PEPROCESS Process,
_In_ PVOID ObjectBody,
_In_ ACCESS_MASK GrantedAccess,
_In_ ULONG HandleCount,
_In_ ULONG SystemHandleCount
);
VOID
NTAPI
PspDeleteJob(
IN PVOID ObjectBody
_In_ PVOID ObjectBody
);
//

File diff suppressed because it is too large Load diff

View file

@ -1120,10 +1120,22 @@ PspExitProcess(IN BOOLEAN LastThread,
ZwSetTimerResolution(KeMaximumIncrement, 0, &Actual);
}
/* Check if we are part of a Job that has a completion port */
if ((Process->Job) && (Process->Job->CompletionPort))
/* Check if we are part of a Job that has a completion port
and do I/O completion if needed */
if (Process->Job &&
Process->Job->CompletionPort &&
!(Process->JobStatus & JOB_NOT_REALLY_ACTIVE))
{
/* FIXME: Check job status code and do I/O completion if needed */
ExEnterCriticalRegionAndAcquireResourceShared(&Process->Job->JobLock);
IoSetIoCompletion(Process->Job->CompletionPort,
Process->Job->CompletionKey,
Process->UniqueProcessId,
STATUS_SUCCESS,
JOB_OBJECT_MSG_EXIT_PROCESS,
FALSE);
ExReleaseResourceAndLeaveCriticalRegion(&Process->Job->JobLock);
}
/* FIXME: Notify the Prefetcher */

View file

@ -376,7 +376,10 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
SECURITY_SUBJECT_CONTEXT SubjectContext;
BOOLEAN NeedsPeb = FALSE;
INITIAL_PEB InitialPeb;
PEJOB Job;
PAGED_CODE();
PSTRACE(PS_PROCESS_DEBUG,
"ProcessHandle: %p Parent: %p\n", ProcessHandle, ParentProcess);
@ -712,8 +715,31 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
/* Check if the parent had a job */
if ((Parent) && (Parent->Job))
{
/* FIXME: We need to insert this process */
DPRINT1("Jobs not yet supported\n");
Job = Parent->Job;
if (!(Job->LimitFlags & JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK))
{
/* Requested to create it without a job */
if (Flags & PROCESS_CREATE_FLAGS_BREAKAWAY)
{
/* Is this allowed? */
if (!(Job->LimitFlags & JOB_OBJECT_LIMIT_BREAKAWAY_OK))
{
Status = STATUS_ACCESS_DENIED;
goto CleanupWithRef;
}
}
else if (InterlockedCompareExchangePointer((PVOID)&Process->Job,
Parent->Job,
NULL) == NULL)
{
Status = PspAssignProcessToJob(Process, Parent->Job);
if (!NT_SUCCESS(Status))
{
goto CleanupWithRef;
}
}
}
}
/* Create PEB only for User-Mode Processes */

View file

@ -434,6 +434,7 @@ PspInitPhase0(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
ObjectTypeInitializer.GenericMapping = PspJobMapping;
ObjectTypeInitializer.InvalidAttributes = 0;
ObjectTypeInitializer.ValidAccessMask = JOB_OBJECT_ALL_ACCESS;
ObjectTypeInitializer.CloseProcedure = PspCloseJob;
ObjectTypeInitializer.DeleteProcedure = PspDeleteJob;
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsJobType);

View file

@ -233,6 +233,22 @@ extern POBJECT_TYPE NTSYSAPI PsJobType;
#define JOB_OBJECT_SECURITY_ONLY_TOKEN 0x0004
#define JOB_OBJECT_SECURITY_FILTER_TOKENS 0x0008
//
// Job message flags
//
#define JOB_OBJECT_MSG_END_OF_JOB_TIME 1
#define JOB_OBJECT_MSG_END_OF_PROCESS_TIME 2
#define JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT 3
#define JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO 4
#define JOB_OBJECT_MSG_NEW_PROCESS 6
#define JOB_OBJECT_MSG_EXIT_PROCESS 7
#define JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS 8
#define JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT 9
#define JOB_OBJECT_MSG_JOB_MEMORY_LIMIT 10
#define JOB_OBJECT_MSG_NOTIFICATION_LIMIT 11
#define JOB_OBJECT_MSG_JOB_CYCLE_TIME_LIMIT 12
//
// Cross Thread Flags
//