From 0e6bc236a11de9c62d64cc8f02473162c208cc44 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 22 Oct 2018 00:39:50 +0200 Subject: [PATCH] [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 0428ed7c8c3..25f8414052b 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 cd643452c2e..0b19924216a 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; } -- 2.17.1