[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.
This commit is contained in:
Hermès Bélusca-Maïto 2020-10-10 17:41:44 +02:00
parent 7790670dd8
commit bd2a40d57b
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0

View file

@ -484,14 +484,22 @@ IopLogWorker(IN PVOID Parameter)
ExFreePoolWithTag(Message, TAG_IO); ExFreePoolWithTag(Message, TAG_IO);
} }
static
VOID VOID
NTAPI 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 */ /* Free the APC */
ExFreePool(Apc); ExFreePoolWithTag(Apc, TAG_APC);
} }
static
VOID VOID
NTAPI NTAPI
IopRaiseHardError(IN PVOID NormalContext, IopRaiseHardError(IN PVOID NormalContext,
@ -657,7 +665,7 @@ IoRaiseHardError(IN PIRP Irp,
IN PVPB Vpb, IN PVPB Vpb,
IN PDEVICE_OBJECT RealDeviceObject) IN PDEVICE_OBJECT RealDeviceObject)
{ {
PETHREAD Thread = (PETHREAD)&Irp->Tail.Overlay.Thread; PETHREAD Thread = Irp->Tail.Overlay.Thread;
PKAPC ErrorApc; PKAPC ErrorApc;
/* Don't do anything if hard errors are disabled on the thread */ /* Don't do anything if hard errors are disabled on the thread */
@ -669,21 +677,29 @@ IoRaiseHardError(IN PIRP Irp,
return; return;
} }
/* Setup an APC */ // TODO: In case we were called in the context of a paging I/O or for
ErrorApc = ExAllocatePoolWithTag(NonPagedPool, // a synchronous operation, that happens with APCs disabled, queue the
sizeof(KAPC), // hard-error call for later processing (see also IofCompleteRequest).
TAG_APC);
/* 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, KeInitializeApc(ErrorApc,
&Thread->Tcb, &Thread->Tcb,
Irp->ApcEnvironment, Irp->ApcEnvironment,
NULL,
IopFreeApc, IopFreeApc,
NULL,
IopRaiseHardError, IopRaiseHardError,
KernelMode, KernelMode,
Irp); Irp);
/* Queue an APC to deal with the error (see osr documentation) */ KeInsertQueueApc(ErrorApc, Vpb, RealDeviceObject, IO_NO_INCREMENT);
KeInsertQueueApc(ErrorApc, Vpb, RealDeviceObject, 0);
} }
/* /*