From b364f702d2fb47133c5c88ce0cd62cd866b2f109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 29 Dec 2024 18:21:16 +0100 Subject: [PATCH] [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. --- ntoskrnl/io/iomgr/device.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ntoskrnl/io/iomgr/device.c b/ntoskrnl/io/iomgr/device.c index d56e6f6881e..a424f23672b 100644 --- a/ntoskrnl/io/iomgr/device.c +++ b/ntoskrnl/io/iomgr/device.c @@ -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; }