Author: tfaber
Date: Thu Aug 14 19:35:00 2014
New Revision: 63883
URL:
http://svn.reactos.org/svn/reactos?rev=63883&view=rev
Log:
[NPFS]
- Fix list walk in NpCancelWaiter -- we cannot access the list entry after using
RemoveEntryList on it
- Make the logic in NpCancelWaiter more readable
CORE-8442 #resolve
Modified:
trunk/reactos/drivers/filesystems/npfs/waitsup.c
Modified: trunk/reactos/drivers/filesystems/npfs/waitsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/npfs/w…
==============================================================================
--- trunk/reactos/drivers/filesystems/npfs/waitsup.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/npfs/waitsup.c [iso-8859-1] Thu Aug 14 19:35:00
2014
@@ -26,11 +26,11 @@
IoReleaseCancelSpinLock(Irp->CancelIrql);
- WaitQueue = (PNP_WAIT_QUEUE)Irp->Tail.Overlay.DriverContext[0];
+ WaitQueue = Irp->Tail.Overlay.DriverContext[0];
KeAcquireSpinLock(&WaitQueue->WaitLock, &OldIrql);
- WaitEntry = (PNP_WAIT_QUEUE_ENTRY)Irp->Tail.Overlay.DriverContext[1];
+ WaitEntry = Irp->Tail.Overlay.DriverContext[1];
if (WaitEntry)
{
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
@@ -102,94 +102,91 @@
NTSTATUS
NTAPI
NpCancelWaiter(IN PNP_WAIT_QUEUE WaitQueue,
- IN PUNICODE_STRING PipeName,
+ IN PUNICODE_STRING PipePath,
IN NTSTATUS Status,
IN PLIST_ENTRY List)
{
- UNICODE_STRING DestinationString;
+ UNICODE_STRING PipePathUpper;
KIRQL OldIrql;
PWCHAR Buffer;
PLIST_ENTRY NextEntry;
PNP_WAIT_QUEUE_ENTRY WaitEntry, Linkage;
PIRP WaitIrp;
PFILE_PIPE_WAIT_FOR_BUFFER WaitBuffer;
- ULONG i, NameLength;
+ UNICODE_STRING WaitName, PipeName;
Linkage = NULL;
Buffer = ExAllocatePoolWithTag(NonPagedPool,
- PipeName->Length,
+ PipePath->Length,
NPFS_WAIT_BLOCK_TAG);
if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
- RtlInitEmptyUnicodeString(&DestinationString, Buffer, PipeName->Length);
- RtlUpcaseUnicodeString(&DestinationString, PipeName, FALSE);
+ RtlInitEmptyUnicodeString(&PipePathUpper, Buffer, PipePath->Length);
+ RtlUpcaseUnicodeString(&PipePathUpper, PipePath, FALSE);
KeAcquireSpinLock(&WaitQueue->WaitLock, &OldIrql);
- for (NextEntry = WaitQueue->WaitList.Flink;
- NextEntry != &WaitQueue->WaitList;
- NextEntry = NextEntry->Flink)
+ NextEntry = WaitQueue->WaitList.Flink;
+ while (NextEntry != &WaitQueue->WaitList)
{
WaitIrp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
+ NextEntry = NextEntry->Flink;
WaitEntry = WaitIrp->Tail.Overlay.DriverContext[1];
if (WaitEntry->AliasName.Length)
{
ASSERT(FALSE);
- if (DestinationString.Length == WaitEntry->AliasName.Length)
- {
- if (RtlCompareMemory(WaitEntry->AliasName.Buffer,
- DestinationString.Buffer,
- DestinationString.Length) ==
- DestinationString.Length)
- {
-CancelWait:
- RemoveEntryList(&WaitIrp->Tail.Overlay.ListEntry);
- if (KeCancelTimer(&WaitEntry->Timer))
- {
- WaitEntry->WaitQueue = (PNP_WAIT_QUEUE)Linkage;
- Linkage = WaitEntry;
- }
- else
- {
- WaitEntry->Irp = NULL;
- WaitIrp->Tail.Overlay.DriverContext[1] = NULL;
- }
-
- if (IoSetCancelRoutine(WaitIrp, NULL))
- {
- WaitIrp->IoStatus.Information = 0;
- WaitIrp->IoStatus.Status = Status;
- InsertTailList(List, &WaitIrp->Tail.Overlay.ListEntry);
- }
- else
- {
- WaitIrp->Tail.Overlay.DriverContext[1] = NULL;
- }
- }
- }
+ /* We have an alias. Use that for comparison */
+ WaitName = WaitEntry->AliasName;
+ PipeName = PipePathUpper;
}
else
{
+ /* Use the name from the wait buffer to compare */
WaitBuffer = WaitIrp->AssociatedIrp.SystemBuffer;
-
- if (WaitBuffer->NameLength + sizeof(WCHAR) == DestinationString.Length)
- {
- NameLength = WaitBuffer->NameLength / sizeof(WCHAR);
- for (i = 0; i < NameLength; i++)
- {
- if (WaitBuffer->Name[i] != DestinationString.Buffer[i + 1])
break;
- }
-
- if (i >= NameLength) goto CancelWait;
+ WaitName.Buffer = WaitBuffer->Name;
+ WaitName.Length = WaitBuffer->NameLength;
+ WaitName.MaximumLength = WaitName.Length;
+
+ /* WaitName doesn't have a leading backslash,
+ * so skip the one in PipePathUpper for the comparison */
+ PipeName.Buffer = PipePathUpper.Buffer + 1;
+ PipeName.Length = PipePathUpper.Length - sizeof(WCHAR);
+ PipeName.MaximumLength = PipeName.Length;
+ }
+
+ if (RtlEqualUnicodeString(&WaitName, &PipeName, FALSE))
+ {
+ /* Found a matching wait. Cancel it */
+ RemoveEntryList(&WaitIrp->Tail.Overlay.ListEntry);
+ if (KeCancelTimer(&WaitEntry->Timer))
+ {
+ WaitEntry->WaitQueue = (PNP_WAIT_QUEUE)Linkage;
+ Linkage = WaitEntry;
+ }
+ else
+ {
+ WaitEntry->Irp = NULL;
+ WaitIrp->Tail.Overlay.DriverContext[1] = NULL;
+ }
+
+ if (IoSetCancelRoutine(WaitIrp, NULL))
+ {
+ WaitIrp->IoStatus.Information = 0;
+ WaitIrp->IoStatus.Status = Status;
+ InsertTailList(List, &WaitIrp->Tail.Overlay.ListEntry);
+ }
+ else
+ {
+ WaitIrp->Tail.Overlay.DriverContext[1] = NULL;
}
}
}
KeReleaseSpinLock(&WaitQueue->WaitLock, OldIrql);
- ExFreePool(DestinationString.Buffer);
+ ExFreePoolWithTag(Buffer, NPFS_WAIT_BLOCK_TAG);
while (Linkage)
{