[FASTFAT]

Add sanity checks in VfatSetRenameInformation() to make sure we don't leak any FCB reference

svn path=/trunk/; revision=65042
This commit is contained in:
Pierre Schweitzer 2014-10-27 13:38:14 +00:00
parent 817dfb57e2
commit 8c225a0e59

View file

@ -473,6 +473,8 @@ VfatSetRenameInformation(
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE TargetHandle; HANDLE TargetHandle;
BOOLEAN DeletedTarget; BOOLEAN DeletedTarget;
ULONG OldReferences, NewReferences;
PVFATFCB OldParent;
DPRINT("VfatSetRenameInfo(%p, %p, %p, %p, %p)\n", FileObject, FCB, DeviceExt, RenameInfo, TargetFileObject); DPRINT("VfatSetRenameInfo(%p, %p, %p, %p, %p)\n", FileObject, FCB, DeviceExt, RenameInfo, TargetFileObject);
@ -482,6 +484,8 @@ VfatSetRenameInformation(
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
OldReferences = FCB->parentFcb->RefCount;
/* If we are performing relative opening for rename, get FO for getting FCB and path name */ /* If we are performing relative opening for rename, get FO for getting FCB and path name */
if (RenameInfo->RootDirectory != NULL) if (RenameInfo->RootDirectory != NULL)
{ {
@ -686,6 +690,7 @@ VfatSetRenameInformation(
if (FsRtlAreNamesEqual(&SourceFile, &NewFile, FALSE, NULL)) if (FsRtlAreNamesEqual(&SourceFile, &NewFile, FALSE, NULL))
{ {
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
ASSERT(OldReferences == FCB->parentFcb->RefCount);
goto Cleanup; goto Cleanup;
} }
@ -729,6 +734,8 @@ VfatSetRenameInformation(
&DeletedTarget); &DeletedTarget);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ASSERT(OldReferences == FCB->parentFcb->RefCount - 1);
ASSERT(OldReferences == ParentFCB->RefCount - 1);
goto Cleanup; goto Cleanup;
} }
@ -773,11 +780,16 @@ VfatSetRenameInformation(
} }
} }
} }
ASSERT(OldReferences == FCB->parentFcb->RefCount - 1); // extra grab
ASSERT(OldReferences == ParentFCB->RefCount - 1); // extra grab
} }
else else
{ {
/* Try to find target */ /* Try to find target */
ParentFCB = NULL; ParentFCB = NULL;
OldParent = FCB->parentFcb;
Status = vfatPrepareTargetForRename(DeviceExt, Status = vfatPrepareTargetForRename(DeviceExt,
&ParentFCB, &ParentFCB,
&NewName, &NewName,
@ -786,9 +798,12 @@ VfatSetRenameInformation(
&DeletedTarget); &DeletedTarget);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ASSERT(OldReferences == FCB->parentFcb->RefCount);
goto Cleanup; goto Cleanup;
} }
NewReferences = ParentFCB->RefCount;
FsRtlNotifyFullReportChange(DeviceExt->NotifySync, FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
&(DeviceExt->NotifyList), &(DeviceExt->NotifyList),
(PSTRING)&FCB->PathNameU, (PSTRING)&FCB->PathNameU,
@ -831,6 +846,8 @@ VfatSetRenameInformation(
} }
} }
ASSERT(OldReferences == OldParent->RefCount + 1); // removed file
ASSERT(NewReferences == ParentFCB->RefCount - 1); // new file
Cleanup: Cleanup:
if (ParentFCB != NULL) vfatReleaseFCB(DeviceExt, ParentFCB); if (ParentFCB != NULL) vfatReleaseFCB(DeviceExt, ParentFCB);
if (NewName.Buffer != NULL) ExFreePoolWithTag(NewName.Buffer, TAG_VFAT); if (NewName.Buffer != NULL) ExFreePoolWithTag(NewName.Buffer, TAG_VFAT);