diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2019-11-06 00:22:01 +0100 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2019-11-07 00:48:09 +0100 |
commit | b7a21b8a76afd7855832f1cf11bff14a3e076e97 (patch) | |
tree | 98a4f0b20f6ea2c7223f0d929a9517536dbae0f9 /src/Driver/Ntvol.c | |
parent | 4587472e8787daf936e63cda35145cd1a363721a (diff) | |
download | VeraCrypt-b7a21b8a76afd7855832f1cf11bff14a3e076e97.tar.gz VeraCrypt-b7a21b8a76afd7855832f1cf11bff14a3e076e97.zip |
Windows Driver: Fix strange crashes caused by probably by APC queue issues from calls to IoBuildDeviceIoControlRequest and ZwCreate (cf https://www.osr.com/blog/2018/02/14/beware-iobuilddeviceiocontrolrequest/)
Diffstat (limited to 'src/Driver/Ntvol.c')
-rw-r--r-- | src/Driver/Ntvol.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/Driver/Ntvol.c b/src/Driver/Ntvol.c index afd3a964..c3344fd0 100644 --- a/src/Driver/Ntvol.c +++ b/src/Driver/Ntvol.c @@ -886,6 +886,18 @@ void TCCloseVolume (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) } } +typedef struct +{ + PDEVICE_OBJECT deviceObject; PEXTENSION Extension; ULONG ioControlCode; void *inputBuffer; int inputBufferSize; void *outputBuffer; int outputBufferSize; + NTSTATUS Status; + KEVENT WorkItemCompletedEvent; +} TCSendHostDeviceIoControlRequestExWorkItemArgs; + +static VOID TCSendHostDeviceIoControlRequestExWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, TCSendHostDeviceIoControlRequestExWorkItemArgs *arg) +{ + arg->Status = TCSendHostDeviceIoControlRequestEx (arg->deviceObject, arg->Extension, arg->ioControlCode, arg->inputBuffer, arg->inputBufferSize, arg->outputBuffer, arg->outputBufferSize); + KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); +} NTSTATUS TCSendHostDeviceIoControlRequestEx (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, @@ -901,6 +913,31 @@ NTSTATUS TCSendHostDeviceIoControlRequestEx (PDEVICE_OBJECT DeviceObject, UNREFERENCED_PARAMETER(DeviceObject); /* Remove compiler warning */ + if ((KeGetCurrentIrql() >= APC_LEVEL) || VC_KeAreAllApcsDisabled()) + { + TCSendHostDeviceIoControlRequestExWorkItemArgs args; + + PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); + if (!workItem) + return STATUS_INSUFFICIENT_RESOURCES; + + args.deviceObject = DeviceObject; + args.Extension = Extension; + args.ioControlCode = IoControlCode; + args.inputBuffer = InputBuffer; + args.inputBufferSize = InputBufferSize; + args.outputBuffer = OutputBuffer; + args.outputBufferSize = OutputBufferSize; + + KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); + IoQueueWorkItem (workItem, TCSendHostDeviceIoControlRequestExWorkItemRoutine, DelayedWorkQueue, &args); + + KeWaitForSingleObject (&args.WorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); + IoFreeWorkItem (workItem); + + return args.Status; + } + KeClearEvent (&Extension->keVolumeEvent); Irp = IoBuildDeviceIoControlRequest (IoControlCode, |