[NTOS:IO] IoGetAttachedDeviceReference/IoGetDeviceAttachmentBaseRef: Retrieve attached device under lock

As implicitly implied by the MSDN description for `IoGetAttachedDevice()`:
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-iogetattacheddevice

> IoGetAttachedDevice differs from IoGetAttachedDeviceReference in the
> following respects:
>
> [...]
>
> - Callers of IoGetAttachedDevice must ensure that no device objects are
>   added to or removed from the stack while IoGetAttachedDevice is executing.
>   Callers that cannot do this must use IoGetAttachedDeviceReference instead.

the `IoGetAttachedDeviceReference()` has to acquire the device list lock
to ensure that no device objects get added to or removed from the device
stack during its invocation.

Similarly, `IoGetDeviceAttachmentBaseRef()` has to do the same.
This commit is contained in:
Hermès Bélusca-Maïto
2026-04-07 20:23:54 +02:00
parent cea19d2e0f
commit b364f702d2
+12 -2
View File
@@ -1406,9 +1406,14 @@ PDEVICE_OBJECT
NTAPI
IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
{
/* Reference the attached device */
KIRQL OldIrql;
/* Retrieve and reference the attached device under the device list lock */
OldIrql = KeAcquireQueuedSpinLock(LockQueueIoDatabaseLock);
DeviceObject = IoGetAttachedDevice(DeviceObject);
ObReferenceObject(DeviceObject);
KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, OldIrql);
return DeviceObject;
}
@@ -1419,9 +1424,14 @@ PDEVICE_OBJECT
NTAPI
IoGetDeviceAttachmentBaseRef(IN PDEVICE_OBJECT DeviceObject)
{
/* Reference the lowest attached device */
KIRQL OldIrql;
/* Retrieve and reference the lowest attached device under the device list lock */
OldIrql = KeAcquireQueuedSpinLock(LockQueueIoDatabaseLock);
DeviceObject = IopGetLowestDevice(DeviceObject);
ObReferenceObject(DeviceObject);
KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, OldIrql);
return DeviceObject;
}