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

commit bd2a40d57b6c13e76ba4659997d9a19cb4e5d8f1
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Sat Oct 10 17:41:44 2020 +0200
Commit:     Hermès Bélusca-Maïto <[email protected]>
CommitDate: Sat Oct 17 16:13:05 2020 +0200

    [NTOS:IO] Some fixes for IoRaiseHardError(). (#3302)
    CORE-14037
    
    - Fix buggy retrieval of the current calling Irp->Tail.Overlay.Thread.
    
    - The 4th argument (KernelRoutine) to the KeInitializeApc() is **NOT**
      optional; however its 5th argument (RundownRoutine) is.
      So use the mandatory routine for freeing the allocated APC instead.
      We don't use the rundown routine yet.
    
    - Check whether the ExAllocatePoolWithTag() call failed or not before
      queueing the allocated APC.
---
 ntoskrnl/io/iomgr/error.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/ntoskrnl/io/iomgr/error.c b/ntoskrnl/io/iomgr/error.c
index 171f02eac80..312b29f942a 100644
--- a/ntoskrnl/io/iomgr/error.c
+++ b/ntoskrnl/io/iomgr/error.c
@@ -484,14 +484,22 @@ IopLogWorker(IN PVOID Parameter)
     ExFreePoolWithTag(Message, TAG_IO);
 }
 
+static
 VOID
 NTAPI
-IopFreeApc(IN PKAPC Apc)
+IopFreeApc(IN PKAPC Apc,
+           IN OUT PKNORMAL_ROUTINE* NormalRoutine,
+           IN OUT PVOID* NormalContext,
+           IN OUT PVOID* SystemArgument1,
+           IN OUT PVOID* SystemArgument2)
 {
+    PAGED_CODE();
+
     /* Free the APC */
-    ExFreePool(Apc);
+    ExFreePoolWithTag(Apc, TAG_APC);
 }
 
+static
 VOID
 NTAPI
 IopRaiseHardError(IN PVOID NormalContext,
@@ -657,7 +665,7 @@ IoRaiseHardError(IN PIRP Irp,
                  IN PVPB Vpb,
                  IN PDEVICE_OBJECT RealDeviceObject)
 {
-    PETHREAD Thread = (PETHREAD)&Irp->Tail.Overlay.Thread;
+    PETHREAD Thread = Irp->Tail.Overlay.Thread;
     PKAPC ErrorApc;
 
     /* Don't do anything if hard errors are disabled on the thread */
@@ -669,21 +677,29 @@ IoRaiseHardError(IN PIRP Irp,
         return;
     }
 
-    /* Setup an APC */
-    ErrorApc = ExAllocatePoolWithTag(NonPagedPool,
-                                     sizeof(KAPC),
-                                     TAG_APC);
+    // TODO: In case we were called in the context of a paging I/O or for
+    // a synchronous operation, that happens with APCs disabled, queue the
+    // hard-error call for later processing (see also IofCompleteRequest).
+
+    /* Setup an APC and queue it to deal with the error (see OSR 
documentation) */
+    ErrorApc = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ErrorApc), TAG_APC);
+    if (!ErrorApc)
+    {
+        /* Fail */
+        IoCompleteRequest(Irp, IO_DISK_INCREMENT);
+        return;
+    }
+
     KeInitializeApc(ErrorApc,
                     &Thread->Tcb,
                     Irp->ApcEnvironment,
-                    NULL,
                     IopFreeApc,
+                    NULL,
                     IopRaiseHardError,
                     KernelMode,
                     Irp);
 
-    /* Queue an APC to deal with the error (see osr documentation) */
-    KeInsertQueueApc(ErrorApc, Vpb, RealDeviceObject, 0);
+    KeInsertQueueApc(ErrorApc, Vpb, RealDeviceObject, IO_NO_INCREMENT);
 }
 
 /*

Reply via email to