[FREELDR] Don't insert a driver into the BootDriver list twice (#755)

This happened for the livecd, where the cdfs driver was inserted twice - once since it is the driver for the boot device, and the 2nd time, because it was specified in the registry - which was then initialized twice by the kernel, leading to a name conflict when trying to create another device object, which resulted in the newly created device object to be dereferenced again and the driver unloaded. This can be seen from the debug message "(ntoskrnl\mm\ARM3\sysldr.c:955) Leaking driver: cdfs.sys"
This commit is contained in:
Timo Kreuzer 2018-08-18 16:41:30 +02:00 committed by GitHub
parent df849213a2
commit 81a9ce44e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -684,6 +684,46 @@ WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
FrLdrHeapFree(GroupNameBuffer, TAG_WLDR_NAME);
}
static
BOOLEAN
InsertInBootDriverList(
PLIST_ENTRY BootDriverListHead,
PBOOT_DRIVER_LIST_ENTRY BootDriverEntry)
{
PBOOT_DRIVER_LIST_ENTRY DriverEntry;
PLIST_ENTRY ListEntry;
ASSERT(BootDriverEntry->FilePath.Buffer != NULL);
ASSERT(BootDriverEntry->RegistryPath.Buffer != NULL);
for (ListEntry = BootDriverListHead->Flink;
ListEntry != BootDriverListHead;
ListEntry = ListEntry->Flink)
{
DriverEntry = CONTAINING_RECORD(ListEntry,
BOOT_DRIVER_LIST_ENTRY,
Link);
if ((DriverEntry->FilePath.Buffer != NULL) &&
RtlEqualUnicodeString(&BootDriverEntry->FilePath,
&DriverEntry->FilePath,
TRUE))
{
return FALSE;
}
if ((DriverEntry->RegistryPath.Buffer != NULL) &&
RtlEqualUnicodeString(&BootDriverEntry->RegistryPath,
&DriverEntry->RegistryPath,
TRUE))
{
return FALSE;
}
}
InsertTailList(BootDriverListHead, &BootDriverEntry->Link);
return TRUE;
}
BOOLEAN
WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
LPWSTR RegistryPath,
@ -782,8 +822,14 @@ WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
if (!NT_SUCCESS(Status))
return FALSE;
// Insert entry at top of the list
InsertTailList(BootDriverListHead, &BootDriverEntry->Link);
// Insert entry into the list
if (!InsertInBootDriverList(BootDriverListHead, BootDriverEntry))
{
// It was already there, so delete our entry
if (BootDriverEntry->FilePath.Buffer) FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
if (BootDriverEntry->RegistryPath.Buffer) FrLdrHeapFree(BootDriverEntry->RegistryPath.Buffer, TAG_WLDR_NAME);
FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
}
return TRUE;
}