[NTOS:CM] CmpCmdHiveOpen(): Resolve FileAttributes->RootDirectory when a hive file name is provided relative to it.

Fixes registry hive loading. CORE-13448
This commit is contained in:
Hermès Bélusca-Maïto 2018-10-22 00:39:50 +02:00
parent 76e2698237
commit 0e6bc236a1
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 95 additions and 5 deletions

View file

@ -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 */

View file

@ -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;
}