[NTOS:IO]

- Introduce IopDriverLoadResource to protect against concurrent driver loading
CORE-8696 #resolve

svn path=/trunk/; revision=64951
This commit is contained in:
Thomas Faber 2014-10-24 10:02:14 +00:00
parent 2c91c440f1
commit fcae57435c
3 changed files with 40 additions and 2 deletions

View file

@ -16,6 +16,8 @@
/* GLOBALS ********************************************************************/
ERESOURCE IopDriverLoadResource;
LIST_ENTRY DriverReinitListHead;
KSPIN_LOCK DriverReinitListLock;
PLIST_ENTRY DriverReinitTailEntry;
@ -113,6 +115,7 @@ IopGetDriverObject(
DPRINT("IopGetDriverObject(%p '%wZ' %x)\n",
DriverObject, ServiceName, FileSystem);
ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource));
*DriverObject = NULL;
/* Create ModuleName string */
@ -313,6 +316,7 @@ IopLoadServiceModule(
HANDLE CCSKey, ServiceKey;
PVOID BaseAddress;
ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource));
ASSERT(ServiceName->Length);
DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
@ -567,6 +571,8 @@ IopAttachFilterDriversCallback(
ServiceName.MaximumLength =
ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR);
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE);
Status = IopGetDriverObject(&DriverObject,
&ServiceName,
FALSE);
@ -575,7 +581,11 @@ IopAttachFilterDriversCallback(
/* Load and initialize the filter driver */
Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
if (!NT_SUCCESS(Status))
{
ExReleaseResourceLite(&IopDriverLoadResource);
KeLeaveCriticalRegion();
return Status;
}
Status = IopInitializeDriverModule(DeviceNode,
ModuleObject,
@ -583,9 +593,16 @@ IopAttachFilterDriversCallback(
FALSE,
&DriverObject);
if (!NT_SUCCESS(Status))
{
ExReleaseResourceLite(&IopDriverLoadResource);
KeLeaveCriticalRegion();
return Status;
}
}
ExReleaseResourceLite(&IopDriverLoadResource);
KeLeaveCriticalRegion();
Status = IopInitializeDevice(DeviceNode, DriverObject);
/* Remove extra reference */
@ -1971,6 +1988,8 @@ IopLoadUnloadDriver(
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 @@ IopLoadUnloadDriver(
if (!NT_SUCCESS(Status))
{
DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
ExReleaseResourceLite(&IopDriverLoadResource);
KeLeaveCriticalRegion();
return Status;
}
@ -2000,6 +2021,8 @@ IopLoadUnloadDriver(
if (!NT_SUCCESS(Status))
{
DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
ExReleaseResourceLite(&IopDriverLoadResource);
KeLeaveCriticalRegion();
MmUnloadSystemImage(ModuleObject);
return Status;
}
@ -2015,16 +2038,24 @@ IopLoadUnloadDriver(
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);
Status = IopStartDevice(DeviceNode);
}
else
{
ExReleaseResourceLite(&IopDriverLoadResource);
KeLeaveCriticalRegion();
DPRINT("DriverObject already exist in ObjectManager\n");
Status = STATUS_IMAGE_ALREADY_LOADED;

View file

@ -54,6 +54,7 @@ extern KSPIN_LOCK ShutdownListLock;
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 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
IopInitLookasideLists();
/* Initialize all locks and lists */
ExInitializeResource(&IopDatabaseResource);
ExInitializeResource(&IopSecurityResource);
ExInitializeResourceLite(&IopDatabaseResource);
ExInitializeResourceLite(&IopSecurityResource);
ExInitializeResourceLite(&IopDriverLoadResource);
KeInitializeGuardedMutex(&PnpNotifyListLock);
InitializeListHead(&IopDiskFileSystemQueueHead);
InitializeListHead(&IopCdRomFileSystemQueueHead);

View file

@ -21,6 +21,7 @@ ERESOURCE PpRegistryDeviceResource;
KGUARDED_MUTEX PpDeviceReferenceTableLock;
RTL_AVL_TABLE PpDeviceReferenceTable;
extern ERESOURCE IopDriverLoadResource;
extern ULONG ExpInitializationPhase;
extern BOOLEAN ExpInTextModeSetup;
extern BOOLEAN PnpSystemInit;
@ -2611,6 +2612,8 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
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 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
if (!BootDrivers) DeviceNode->Problem = CM_PROB_DRIVER_FAILED_LOAD;
}
}
ExReleaseResourceLite(&IopDriverLoadResource);
KeLeaveCriticalRegion();
/* Driver is loaded and initialized at this point */
if (NT_SUCCESS(Status))