From: Pierre Schweitzer Date: Mon, 13 Aug 2018 06:24:39 +0000 (+0200) Subject: [NTOSKRNL] Keep page file name along the page file and free it on shutdown X-Git-Tag: 0.4.11-dev~159 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=34e8f45122982e43a7f73ebed7d71d43d31020cc [NTOSKRNL] Keep page file name along the page file and free it on shutdown --- diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h index 6f0972da40f..38b34cd74f2 100644 --- a/ntoskrnl/include/internal/mm.h +++ b/ntoskrnl/include/internal/mm.h @@ -434,6 +434,7 @@ typedef struct _MMPAGING_FILE PFN_NUMBER UsedPages; PRTL_BITMAP AllocMap; KSPIN_LOCK AllocMapLock; + UNICODE_STRING PageFileName; } MMPAGING_FILE, *PMMPAGING_FILE; diff --git a/ntoskrnl/mm/pagefile.c b/ntoskrnl/mm/pagefile.c index 2859a35fd10..29cfdbc820a 100644 --- a/ntoskrnl/mm/pagefile.c +++ b/ntoskrnl/mm/pagefile.c @@ -376,11 +376,12 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, ULONG AllocMapSize; ULONG Count; KPROCESSOR_MODE PreviousMode; - UNICODE_STRING CapturedFileName; + UNICODE_STRING PageFileName; LARGE_INTEGER SafeInitialSize, SafeMaximumSize, AllocationSize; FILE_FS_DEVICE_INFORMATION FsDeviceInfo; SECURITY_DESCRIPTOR SecurityDescriptor; PACL Dacl; + PWSTR Buffer; DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n", FileName, InitialSize->QuadPart); @@ -403,6 +404,10 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, { SafeInitialSize = ProbeForReadLargeInteger(InitialSize); SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize); + + PageFileName.Length = FileName->Length; + PageFileName.MaximumLength = FileName->MaximumLength; + PageFileName.Buffer = FileName->Buffer; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -415,6 +420,10 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, { SafeInitialSize = *InitialSize; SafeMaximumSize = *MaximumSize; + + PageFileName.Length = FileName->Length; + PageFileName.MaximumLength = FileName->MaximumLength; + PageFileName.Buffer = FileName->Buffer; } /* Pagefiles can't be larger than 4GB and ofcourse the minimum should be @@ -432,20 +441,55 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, return STATUS_INVALID_PARAMETER_MIX; } - Status = ProbeAndCaptureUnicodeString(&CapturedFileName, - PreviousMode, - FileName); - if (!NT_SUCCESS(Status)) + /* Validate name length */ + if (PageFileName.Length > 128 * sizeof(WCHAR)) + { + return STATUS_OBJECT_NAME_INVALID; + } + + /* We won't care about any potential UNICODE_NULL */ + PageFileName.MaximumLength = PageFileName.Length; + /* Allocate a buffer to keep name copy */ + Buffer = ExAllocatePoolWithTag(PagedPool, PageFileName.Length, TAG_MM); + if (Buffer == NULL) { - return(Status); + return STATUS_INSUFFICIENT_RESOURCES; } + /* Copy name */ + if (PreviousMode != KernelMode) + { + _SEH2_TRY + { + if (PageFileName.Length != 0) + { + ProbeForRead(PageFileName.Buffer, PageFileName.Length, sizeof(WCHAR)); + } + + RtlCopyMemory(Buffer, PageFileName.Buffer, PageFileName.Length); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + ExFreePoolWithTag(Buffer, TAG_MM); + + /* Return the exception code */ + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END; + } + else + { + RtlCopyMemory(Buffer, PageFileName.Buffer, PageFileName.Length); + } + + /* Erase caller's buffer with ours */ + PageFileName.Buffer = Buffer; + /* Create the security descriptor for the page file */ Status = RtlCreateSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) { - ReleaseCapturedUnicodeString(&CapturedFileName, - PreviousMode); + ExFreePoolWithTag(Buffer, TAG_MM); return Status; } @@ -455,8 +499,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, Dacl = ExAllocatePoolWithTag(PagedPool, Count, 'lcaD'); if (Dacl == NULL) { - ReleaseCapturedUnicodeString(&CapturedFileName, - PreviousMode); + ExFreePoolWithTag(Buffer, TAG_MM); return STATUS_INSUFFICIENT_RESOURCES; } @@ -465,8 +508,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(Dacl, 'lcaD'); - ReleaseCapturedUnicodeString(&CapturedFileName, - PreviousMode); + ExFreePoolWithTag(Buffer, TAG_MM); return Status; } @@ -475,8 +517,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(Dacl, 'lcaD'); - ReleaseCapturedUnicodeString(&CapturedFileName, - PreviousMode); + ExFreePoolWithTag(Buffer, TAG_MM); return Status; } @@ -485,8 +526,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(Dacl, 'lcaD'); - ReleaseCapturedUnicodeString(&CapturedFileName, - PreviousMode); + ExFreePoolWithTag(Buffer, TAG_MM); return Status; } @@ -495,13 +535,12 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(Dacl, 'lcaD'); - ReleaseCapturedUnicodeString(&CapturedFileName, - PreviousMode); + ExFreePoolWithTag(Buffer, TAG_MM); return Status; } InitializeObjectAttributes(&ObjectAttributes, - &CapturedFileName, + &PageFileName, OBJ_KERNEL_HANDLE, NULL, &SecurityDescriptor); @@ -551,13 +590,12 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING); } - ReleaseCapturedUnicodeString(&CapturedFileName, - PreviousMode); if (!NT_SUCCESS(Status)) { DPRINT1("Failed creating page file: %lx\n", Status); ExFreePoolWithTag(Dacl, 'lcaD'); - return(Status); + ExFreePoolWithTag(Buffer, TAG_MM); + return Status; } /* Set the security descriptor */ @@ -568,6 +606,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, { ExFreePoolWithTag(Dacl, 'lcaD'); ZwClose(FileHandle); + ExFreePoolWithTag(Buffer, TAG_MM); return Status; } } @@ -584,7 +623,8 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, if (!NT_SUCCESS(Status) || !NT_SUCCESS(IoStatus.Status)) { ZwClose(FileHandle); - return(Status); + ExFreePoolWithTag(Buffer, TAG_MM); + return Status; } Status = ObReferenceObjectByHandle(FileHandle, @@ -596,7 +636,8 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, if (!NT_SUCCESS(Status)) { ZwClose(FileHandle); - return(Status); + ExFreePoolWithTag(Buffer, TAG_MM); + return Status; } /* Deny page file creation on a floppy disk */ @@ -606,6 +647,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, { ObDereferenceObject(FileObject); ZwClose(FileHandle); + ExFreePoolWithTag(Buffer, TAG_MM); return STATUS_FLOPPY_VOLUME; } @@ -614,7 +656,8 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, { ObDereferenceObject(FileObject); ZwClose(FileHandle); - return(STATUS_NO_MEMORY); + ExFreePoolWithTag(Buffer, TAG_MM); + return STATUS_NO_MEMORY; } RtlZeroMemory(PagingFile, sizeof(*PagingFile)); @@ -626,6 +669,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, PagingFile->FreePages = (ULONG)(SafeInitialSize.QuadPart / PAGE_SIZE); PagingFile->UsedPages = 0; KeInitializeSpinLock(&PagingFile->AllocMapLock); + PagingFile->PageFileName = PageFileName; AllocMapSize = sizeof(RTL_BITMAP) + (((PagingFile->FreePages + 31) / 32) * sizeof(ULONG)); PagingFile->AllocMap = ExAllocatePoolWithTag(NonPagedPool, @@ -636,7 +680,8 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName, ExFreePool(PagingFile); ObDereferenceObject(FileObject); ZwClose(FileHandle); - return(STATUS_NO_MEMORY); + ExFreePoolWithTag(Buffer, TAG_MM); + return STATUS_NO_MEMORY; } RtlInitializeBitMap(PagingFile->AllocMap, diff --git a/ntoskrnl/mm/shutdown.c b/ntoskrnl/mm/shutdown.c index d4093015ffa..c80cc527a30 100644 --- a/ntoskrnl/mm/shutdown.c +++ b/ntoskrnl/mm/shutdown.c @@ -25,6 +25,11 @@ MiShutdownSystem(VOID) /* Loop through all the paging files */ for (i = 0; i < MmNumberOfPagingFiles; i++) { + /* Free page file name */ + ASSERT(MmPagingFile[i]->PageFileName.Buffer != NULL); + ExFreePoolWithTag(MmPagingFile[i]->PageFileName.Buffer, TAG_MM); + MmPagingFile[i]->PageFileName.Buffer = NULL; + /* And close them */ ZwClose(MmPagingFile[i]->FileHandle); }