Author: tfaber Date: Fri Oct 24 10:02:14 2014 New Revision: 64951
URL: http://svn.reactos.org/svn/reactos?rev=64951&view=rev Log: [NTOS:IO] - Introduce IopDriverLoadResource to protect against concurrent driver loading CORE-8696 #resolve
Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c trunk/reactos/ntoskrnl/io/iomgr/iomgr.c trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/driver.c?... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] Fri Oct 24 10:02:14 2014 @@ -16,6 +16,8 @@
/* GLOBALS ********************************************************************/
+ERESOURCE IopDriverLoadResource; + LIST_ENTRY DriverReinitListHead; KSPIN_LOCK DriverReinitListLock; PLIST_ENTRY DriverReinitTailEntry; @@ -113,6 +115,7 @@ DPRINT("IopGetDriverObject(%p '%wZ' %x)\n", DriverObject, ServiceName, FileSystem);
+ ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource)); *DriverObject = NULL;
/* Create ModuleName string */ @@ -313,6 +316,7 @@ HANDLE CCSKey, ServiceKey; PVOID BaseAddress;
+ ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource)); ASSERT(ServiceName->Length); DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
@@ -567,6 +571,8 @@ ServiceName.MaximumLength = ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR);
+ KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE); Status = IopGetDriverObject(&DriverObject, &ServiceName, FALSE); @@ -575,7 +581,11 @@ /* Load and initialize the filter driver */ Status = IopLoadServiceModule(&ServiceName, &ModuleObject); if (!NT_SUCCESS(Status)) + { + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); return Status; + }
Status = IopInitializeDriverModule(DeviceNode, ModuleObject, @@ -583,8 +593,15 @@ FALSE, &DriverObject); if (!NT_SUCCESS(Status)) + { + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); return Status; - } + } + } + + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion();
Status = IopInitializeDevice(DeviceNode, DriverObject);
@@ -1971,6 +1988,8 @@ DPRINT("FullImagePath: '%wZ'\n", &ImagePath); DPRINT("Type: %lx\n", Type);
+ KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE); /* * Get existing DriverObject pointer (in case the driver * has already been loaded and initialized). @@ -1990,6 +2009,8 @@ if (!NT_SUCCESS(Status)) { DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status); + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); return Status; }
@@ -2000,6 +2021,8 @@ if (!NT_SUCCESS(Status)) { DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status); + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); MmUnloadSystemImage(ModuleObject); return Status; } @@ -2015,9 +2038,14 @@ if (!NT_SUCCESS(Status)) { DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status); + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); MmUnloadSystemImage(ModuleObject); return Status; } + + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion();
/* Initialize and start device */ IopInitializeDevice(DeviceNode, *DriverObject); @@ -2025,6 +2053,9 @@ } else { + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); + DPRINT("DriverObject already exist in ObjectManager\n"); Status = STATUS_IMAGE_ALREADY_LOADED;
Modified: trunk/reactos/ntoskrnl/io/iomgr/iomgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iomgr.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/iomgr.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/iomgr/iomgr.c [iso-8859-1] Fri Oct 24 10:02:14 2014 @@ -54,6 +54,7 @@ extern POBJECT_TYPE IoAdapterObjectType; extern ERESOURCE IopDatabaseResource; ERESOURCE IopSecurityResource; +extern ERESOURCE IopDriverLoadResource; extern KGUARDED_MUTEX PnpNotifyListLock; extern LIST_ENTRY IopDiskFileSystemQueueHead; extern LIST_ENTRY IopCdRomFileSystemQueueHead; @@ -476,8 +477,9 @@ IopInitLookasideLists();
/* Initialize all locks and lists */ - ExInitializeResource(&IopDatabaseResource); - ExInitializeResource(&IopSecurityResource); + ExInitializeResourceLite(&IopDatabaseResource); + ExInitializeResourceLite(&IopSecurityResource); + ExInitializeResourceLite(&IopDriverLoadResource); KeInitializeGuardedMutex(&PnpNotifyListLock); InitializeListHead(&IopDiskFileSystemQueueHead); InitializeListHead(&IopCdRomFileSystemQueueHead);
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c... ============================================================================== --- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Fri Oct 24 10:02:14 2014 @@ -21,6 +21,7 @@ KGUARDED_MUTEX PpDeviceReferenceTableLock; RTL_AVL_TABLE PpDeviceReferenceTable;
+extern ERESOURCE IopDriverLoadResource; extern ULONG ExpInitializationPhase; extern BOOLEAN ExpInTextModeSetup; extern BOOLEAN PnpSystemInit; @@ -2611,6 +2612,8 @@ PLDR_DATA_TABLE_ENTRY ModuleObject; PDRIVER_OBJECT DriverObject;
+ KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE); /* Get existing DriverObject pointer (in case the driver has already been loaded and initialized) */ Status = IopGetDriverObject( @@ -2642,6 +2645,8 @@ if (!BootDrivers) DeviceNode->Problem = CM_PROB_DRIVER_FAILED_LOAD; } } + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion();
/* Driver is loaded and initialized at this point */ if (NT_SUCCESS(Status))