https://git.reactos.org/?p=reactos.git;a=commitdiff;h=81a9ce44e9a1945c069e26cc7cd48c3dc91645c8

commit 81a9ce44e9a1945c069e26cc7cd48c3dc91645c8
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Sat Aug 18 16:41:30 2018 +0200
Commit:     GitHub <[email protected]>
CommitDate: Sat Aug 18 16:41:30 2018 +0200

    [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 drive [...]
---
 boot/freeldr/freeldr/ntldr/wlregistry.c | 50 +++++++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/boot/freeldr/freeldr/ntldr/wlregistry.c 
b/boot/freeldr/freeldr/ntldr/wlregistry.c
index b280250142..bf194027cf 100644
--- a/boot/freeldr/freeldr/ntldr/wlregistry.c
+++ b/boot/freeldr/freeldr/ntldr/wlregistry.c
@@ -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;
 }

Reply via email to