https://git.reactos.org/?p=reactos.git;a=commitdiff;h=34e8f45122982e43a7f73…
commit 34e8f45122982e43a7f73ebed7d71d43d31020cc
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Mon Aug 13 08:24:39 2018 +0200
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Mon Aug 13 08:30:17 2018 +0200
[NTOSKRNL] Keep page file name along the page file and free it on shutdown
---
ntoskrnl/include/internal/mm.h | 1 +
ntoskrnl/mm/pagefile.c | 97 +++++++++++++++++++++++++++++++-----------
ntoskrnl/mm/shutdown.c | 5 +++
3 files changed, 77 insertions(+), 26 deletions(-)
diff --git a/ntoskrnl/include/internal/mm.h b/ntoskrnl/include/internal/mm.h
index 6f0972da40..38b34cd74f 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 2859a35fd1..29cfdbc820 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 d4093015ff..c80cc527a3 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);
}