Assertion failed: Pfn1->u3.e2.ReferenceCount < MmReferenceCountCheck

Hi, devs, I need some help:

I´m writing a FSF which monitors each IRP_MJ_CREATE, and then checks if the
file just opened is a special type of file.

For this purpose, I pass the IRP_MJ_CREATE down to the attached device and
wait for its completion. Then I do the file check. For this purpose I need
to do some read operations, which I perform building my own read IRPs and
passing them down to the underlying driver.

The scheme seemed to work very well, and is being tested in a NT 4.0 SP6
checked platform.

But today, just to stress my FSF a little bit, I tried a simple program that
did the following operation 1000 times: CreateFile, GetFileSize,
CloseHandle. That´s it.

Well, after one hundred or so of iterations, I get the following assertion
error when passing down the read IRP (using IoCallDriver):

*** assertion failed: Pfn1->u3.e2.ReferenceCount < MmReferenceCountCheck2
*** source file: w:\nt\private\ntos\mm\up..\iosup.c, line 456

The meaning seems rather evident: there is a reference count going out of
bounds, but I gave no clue to which objects it refers to.

Since this happens only after about 100 iterations
(open/get_file_size/close):
It seems not to be the IRP itself, since a different one is created and
freed for each read operation.
It seems not to be the FileObject, since it is a different one for each
OPEN/GETFILESIZE/CLOSE operation.

Any clues / directions ?. I would appreciate them very much.

Note: I don´t use IoBuildSynchronousFsdRequest, and I think it was because I
had initialy some problems with it and got this approach working rather
fast. However, since I cook the whole read IRP myself, perhaps I´m
forgetting some obscure but important field… I attach my code at the end
of the message just in case some brave dev wants to have a look to it :slight_smile:

Thanks. Nacho.

static NTSTATUS irpCompletion(
PDEVICE_OBJECT deviceObject,
PIRP irp,
PVOID context
)
{
*irp->UserIosb = irp->IoStatus; // Copy status information to
// the user
KeSetEvent(irp->UserEvent, 0, FALSE); // Signal event
IoFreeIrp(irp); // Free IRP
return STATUS_MORE_PROCESSING_REQUIRED; // Tell the I/O manager to stop
}

BOOLEAN irpRead(
PDEVICE_OBJECT hookedDevice,
PFILE_OBJECT fileObject,
PLARGE_INTEGER offset,
PVOID buffer,
ULONG length
)
{
PIRP irp;
PIO_STACK_LOCATION irpSp;
KEVENT event;
IO_STATUS_BLOCK ioStatus;

irp = IoAllocateIrp(hookedDevice->StackSize, FALSE);
if (irp == NULL) {
return FALSE;
}

KeInitializeEvent(&event, NotificationEvent, FALSE);

// Read uses neither I/O, so we must pass the buffer in UserBuffer

irp->UserBuffer = buffer;
irp->UserEvent = &event;
irp->UserIosb = &ioStatus;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = fileObject;
irp->RequestorMode = KernelMode;
irp->Flags = IRP_READ_OPERATION | IRP_NOCACHE;

irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_READ;
irpSp->MinorFunction = 0;
irpSp->DeviceObject = hookedDevice;
irpSp->FileObject = fileObject;
irpSp->Parameters.Read.Length = length;
irpSp->Parameters.Read.Key = 0;
irpSp->Parameters.Read.ByteOffset = *offset;

IoSetCompletionRoutine(irp, irpCompletion, 0, TRUE, TRUE, TRUE);
DbgPrint((“??? About to call IoCallDriver for direct IRP read\n”));
IoCallDriver(hookedDevice, irp);
DbgPrint((“??? Just called IoCallDriver for direct IRP read\n”));
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);

return NT_SUCCESS(ioStatus.Status) && // Success only if we could
ioStatus.Information == length; // read all requested data
}


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> Well, after one hundred or so of iterations, I get the following assertion

error when passing down the read IRP (using IoCallDriver):

*** assertion failed: Pfn1->u3.e2.ReferenceCount < MmReferenceCountCheck2
*** source file: w:\nt\private\ntos\mm\up..\iosup.c, line 456

The meaning seems rather evident: there is a reference count going out of
bounds, but I gave no clue to which objects it refers to.

The per-page lock count which is incremented by MmProbeAndLockPages.

Max


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com