From 28b4b419c249c004f0b6cd89012aaf72bb78ea67 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Fri, 10 Aug 2018 08:40:02 +0200 Subject: [PATCH] [NTOSKRNL] Restrict rights on the page file --- ntoskrnl/mm/pagefile.c | 80 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/ntoskrnl/mm/pagefile.c b/ntoskrnl/mm/pagefile.c index 7e73002153c..32dda85de09 100644 --- a/ntoskrnl/mm/pagefile.c +++ b/ntoskrnl/mm/pagefile.c @@ -505,6 +505,8 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, UNICODE_STRING CapturedFileName; LARGE_INTEGER SafeInitialSize, SafeMaximumSize, AllocationSize; FILE_FS_DEVICE_INFORMATION FsDeviceInfo; + SECURITY_DESCRIPTOR SecurityDescriptor; + PACL Dacl; DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n", FileName, InitialSize->QuadPart); @@ -564,11 +566,71 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, return(Status); } + /* Create the security descriptor for the page file */ + Status = RtlCreateSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); + if (!NT_SUCCESS(Status)) + { + ReleaseCapturedUnicodeString(&CapturedFileName, + PreviousMode); + return Status; + } + + /* Create the DACL: we will only allow two SIDs */ + Count = sizeof(ACL) + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) + + (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)); + Dacl = ExAllocatePoolWithTag(PagedPool, Count, 'lcaD'); + if (Dacl == NULL) + { + ReleaseCapturedUnicodeString(&CapturedFileName, + PreviousMode); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Initialize the DACL */ + Status = RtlCreateAcl(Dacl, Count, ACL_REVISION); + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(Dacl, 'lcaD'); + ReleaseCapturedUnicodeString(&CapturedFileName, + PreviousMode); + return Status; + } + + /* Grant full access to admins */ + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, FILE_ALL_ACCESS, SeAliasAdminsSid); + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(Dacl, 'lcaD'); + ReleaseCapturedUnicodeString(&CapturedFileName, + PreviousMode); + return Status; + } + + /* Grant full access to SYSTEM */ + Status = RtlAddAccessAllowedAce(Dacl, ACL_REVISION, FILE_ALL_ACCESS, SeLocalSystemSid); + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(Dacl, 'lcaD'); + ReleaseCapturedUnicodeString(&CapturedFileName, + PreviousMode); + return Status; + } + + /* Attach the DACL to the security descriptor */ + Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl, FALSE); + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(Dacl, 'lcaD'); + ReleaseCapturedUnicodeString(&CapturedFileName, + PreviousMode); + return Status; + } + InitializeObjectAttributes(&ObjectAttributes, &CapturedFileName, OBJ_KERNEL_HANDLE, NULL, - NULL); + &SecurityDescriptor); /* Make sure we can at least store a complete page: * If we have 2048 BytesPerAllocationUnit (FAT16 < 128MB) there is @@ -620,9 +682,25 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, if (!NT_SUCCESS(Status)) { DPRINT1("Failed creating page file: %lx\n", Status); + ExFreePoolWithTag(Dacl, 'lcaD'); return(Status); } + /* Set the security descriptor */ + if (NT_SUCCESS(IoStatus.Status)) + { + Status = ZwSetSecurityObject(FileHandle, DACL_SECURITY_INFORMATION, &SecurityDescriptor); + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(Dacl, 'lcaD'); + ZwClose(FileHandle); + return Status; + } + } + + /* DACL is no longer needed, free it */ + ExFreePoolWithTag(Dacl, 'lcaD'); + Status = ZwQueryVolumeInformationFile(FileHandle, &IoStatus, &FsSizeInformation,