https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bd2a40d57b6c13e76ba46…
commit bd2a40d57b6c13e76ba4659997d9a19cb4e5d8f1
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat Oct 10 17:41:44 2020 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
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);
}
/*