https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0e6bc236a11de9c62d64c…
commit 0e6bc236a11de9c62d64cc8f02473162c208cc44
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Oct 22 00:39:50 2018 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Mon Oct 22 00:39:50 2018 +0200
[NTOS:CM] CmpCmdHiveOpen(): Resolve FileAttributes->RootDirectory when a hive file
name is provided relative to it.
Fixes registry hive loading. CORE-13448
---
ntoskrnl/config/cmhvlist.c | 3 +-
ntoskrnl/config/cmlazy.c | 97 ++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 95 insertions(+), 5 deletions(-)
diff --git a/ntoskrnl/config/cmhvlist.c b/ntoskrnl/config/cmhvlist.c
index 0428ed7c8c..25f8414052 100644
--- a/ntoskrnl/config/cmhvlist.c
+++ b/ntoskrnl/config/cmhvlist.c
@@ -136,7 +136,8 @@ CmpAddToHiveFileList(IN PCMHIVE Hive)
PWCHAR FilePath;
UCHAR Buffer[sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
ULONG Length = sizeof(Buffer);
- POBJECT_NAME_INFORMATION FileNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
+ POBJECT_NAME_INFORMATION FileNameInfo = (POBJECT_NAME_INFORMATION)Buffer;
+
HivePath.Buffer = NULL;
/* Create or open the hive list key */
diff --git a/ntoskrnl/config/cmlazy.c b/ntoskrnl/config/cmlazy.c
index cd643452c2..0b19924216 100644
--- a/ntoskrnl/config/cmlazy.c
+++ b/ntoskrnl/config/cmlazy.c
@@ -274,13 +274,97 @@ CmpCmdHiveOpen(IN POBJECT_ATTRIBUTES FileAttributes,
OUT PCMHIVE *NewHive,
IN ULONG CheckFlags)
{
- PUNICODE_STRING FileName;
NTSTATUS Status;
+ UNICODE_STRING FileName;
+ PWCHAR FilePath;
+ UCHAR Buffer[sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
+ ULONG Length = sizeof(Buffer);
+ POBJECT_NAME_INFORMATION FileNameInfo = (POBJECT_NAME_INFORMATION)Buffer;
+
PAGED_CODE();
+ if (FileAttributes->RootDirectory)
+ {
+ /*
+ * Validity check: The ObjectName is relative to RootDirectory,
+ * therefore it must not start with a path separator.
+ */
+ if (FileAttributes->ObjectName &&
FileAttributes->ObjectName->Buffer &&
+ FileAttributes->ObjectName->Length >= sizeof(WCHAR) &&
+ *FileAttributes->ObjectName->Buffer == OBJ_NAME_PATH_SEPARATOR)
+ {
+ return STATUS_OBJECT_PATH_SYNTAX_BAD;
+ }
+
+ /* Try to get the value */
+ Status = ZwQueryObject(FileAttributes->RootDirectory,
+ ObjectNameInformation,
+ FileNameInfo,
+ Length,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ DPRINT1("CmpCmdHiveOpen(): Root directory handle object name query
failed, Status = 0x%08lx\n", Status);
+ return Status;
+ }
+
+ /* Null-terminate and add the length of the terminator */
+ Length -= sizeof(OBJECT_NAME_INFORMATION);
+ FilePath = FileNameInfo->Name.Buffer;
+ FilePath[Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Length += sizeof(UNICODE_NULL);
+
+ /* Compute the size of the full path; Length already counts the terminating NULL
*/
+ Length = Length + sizeof(WCHAR) + FileAttributes->ObjectName->Length;
+ if (Length > MAXUSHORT)
+ {
+ /* Name size too long, bail out */
+ return STATUS_OBJECT_PATH_INVALID;
+ }
+
+ /* Build the full path */
+ RtlInitEmptyUnicodeString(&FileName, NULL, 0);
+ FileName.Buffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_CM);
+ if (!FileName.Buffer)
+ {
+ /* Fail */
+ DPRINT1("CmpCmdHiveOpen(): Unable to allocate memory\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ FileName.MaximumLength = Length;
+ RtlCopyUnicodeString(&FileName, &FileNameInfo->Name);
+
+ /*
+ * Append a path terminator if needed (we have already accounted
+ * for a possible extra one when allocating the buffer).
+ */
+ if (/* FileAttributes->ObjectName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR
&& */ // We excluded ObjectName starting with a path separator above.
+ FileName.Length > 0 && FileName.Buffer[FileName.Length /
sizeof(WCHAR) - 1] != OBJ_NAME_PATH_SEPARATOR)
+ {
+ /* ObjectName does not start with '\' and PathBuffer does not end
with '\' */
+ FileName.Buffer[FileName.Length / sizeof(WCHAR)] = OBJ_NAME_PATH_SEPARATOR;
+ FileName.Length += sizeof(WCHAR);
+ FileName.Buffer[FileName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ }
+
+ /* Append the object name */
+ Status = RtlAppendUnicodeStringToString(&FileName,
FileAttributes->ObjectName);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ DPRINT1("CmpCmdHiveOpen(): RtlAppendUnicodeStringToString() failed,
Status = 0x%08lx\n", Status);
+ ExFreePoolWithTag(FileName.Buffer, TAG_CM);
+ return Status;
+ }
+ }
+ else
+ {
+ FileName = *FileAttributes->ObjectName;
+ }
+
/* Open the file in the current security context */
- FileName = FileAttributes->ObjectName;
- Status = CmpInitHiveFromFile(FileName,
+ Status = CmpInitHiveFromFile(&FileName,
0,
NewHive,
Allocate,
@@ -298,7 +382,7 @@ CmpCmdHiveOpen(IN POBJECT_ATTRIBUTES FileAttributes,
if (NT_SUCCESS(Status))
{
/* Now try again */
- Status = CmpInitHiveFromFile(FileName,
+ Status = CmpInitHiveFromFile(&FileName,
0,
NewHive,
Allocate,
@@ -309,6 +393,11 @@ CmpCmdHiveOpen(IN POBJECT_ATTRIBUTES FileAttributes,
}
}
+ if (FileAttributes->RootDirectory)
+ {
+ ExFreePoolWithTag(FileName.Buffer, TAG_CM);
+ }
+
/* Return status of open attempt */
return Status;
}