IFS kit bug: SFILTER

Hi all,

this seems to be a bug.
sfilter.c line 1181:

//
// Pass a pointer to the real device object from the VPB so
// that a remount VPB can be located if necessary (see comments in
// the mount completion routine).
//

irpSp->Parameters.MountVolume.DeviceObject = irpSp->Parameters.MountVolume.Vpb->RealDevice;

This is a wrong idea.

Vpb->RealDevice is a bottom-most disk device in the attachment stack.
Parameters.MountVolume.DeviceObject is a target disk device object to which the FSD will send all disk IRPs. Surely this must be a
top-most disk device in the attachment stack.

SFILTER code “as is” (and thus any FSFs based on it) ignores any block-level disk filter drivers. This is very bad.
The yet another comment in SFILTER confirms this.

// pointer to the real device, not the device that the file system
// was supposed to talk to, since this driver does not care.
//

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

No, Max, you are incorrect here. Sfilter is doing the right thing.

In the storage stack, there is exactly one device object that will have
a VPB that will point back to the file system’s device object once the
mount process has successfully completed. A file system filter can find
out who this “one true” storage device object, the RealDevice, is by
looking at irpSp->Parmeters.MountVolume.Vpb->RealDevice before the mount
request is passed down to the file system.

The file system can tell what device object is at the top of the storage
stack so that it will not bypass any block-level disk filters by looking
at the second parameter to a mount request,
irpSp->Parameters.MountVolume.DeviceObject.

File system filters need to know the RealDevice so that they can find
the correct VPB that will point back to the file system device object
once the mount has succeeded. Often other device objects in the storage
stack will have non-NULL VPBs, but those will not point back to the file
system device object. This problem caught a lot of folks at the Windows
XP plugfests since this was the first time many of these file system
filters had been run on a machine with a storage stack filter (Windows
XP has the storage filter volsnap.sys).

It may seem odd that sfilter remembers the RealDevice instead of the
VPB, but this is necessary because file systems that deal with removable
media (like FAT) can change the VPB during the mount process.

Sfilter should never be sending IO’s directly to the storage stack,
therefore, it really doesn’t need to remember any device objects that
are in the storage stack once it has attached to the file system device
stack. Sfilter does remember the RealDevice because it is useful for
debugging – it is named and has the VPB that links us back to the file
system stack.

This functionality in sfilter hasn’t changed since NT 4.0, but people
with the Windows XP version of the IFS Kit will notice that we cleaned
this up a bit and added better comments.

Thanks,

Molly Brown
Microsoft Corporation

-----Original Message-----
From: Maxim S. Shatskih [mailto:xxxxx@storagecraft.com]
Sent: Thursday, September 27, 2001 10:37 AM
To: File Systems Developers
Subject: [ntfsd] IFS kit bug: SFILTER

Hi all,

this seems to be a bug.
sfilter.c line 1181:

//
// Pass a pointer to the real device object from the VPB so
// that a remount VPB can be located if necessary (see
comments in
// the mount completion routine).
//

irpSp->Parameters.MountVolume.DeviceObject =
irpSp->Parameters.MountVolume.Vpb->RealDevice;

This is a wrong idea.

Vpb->RealDevice is a bottom-most disk device in the attachment stack.
Parameters.MountVolume.DeviceObject is a target disk device object to
which the FSD will send all disk IRPs. Surely this must be a top-most
disk device in the attachment stack.

SFILTER code “as is” (and thus any FSFs based on it) ignores any
block-level disk filter drivers. This is very bad. The yet another
comment in SFILTER confirms this.

// pointer to the real device, not the device that the file
system
// was supposed to talk to, since this driver does not
care.
//

Max


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


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

>No, Max, you are incorrect here. Sfilter is doing the right thing.

Thanks Molly, I was wrong - overlooked something in SFILTER.

For a mount IRP, SFILTER does:

  • copies the current IRP stack location to next.
  • patches the Parameters.MountVolume.DeviceObject in CurrentLoc and not NextLoc. CurrentLoc is just SFILTER’s private storage area
    here, not a mean of passing parameters to the lower driver. FSD will not know on CurrentLoc contents - only NextLoc one.
  • the device object the FSD will see is in NextLoc and not CurrentLoc, and it is the device object arrived in the original IRP.

So, I confused CurrentLoc and NextLoc. SFILTER just plays a good old trick of using the CurrentLoc as a context storage to pass data
to the completion path.

As about the VPB manipulations in SFILTER - yes, I understood the purpose of them including the VPB changes at remount, thanks for
explaining it once more.

This problem caught a lot of folks at the Windows XP plugfests since this was the first time
many of these file system filters had been run on a machine with a storage stack filter
(Windows XP has the storage filter volsnap.sys).

Looks like it is another good candidate to be added to Driver Verifier.
I mean - adding some dummy filter DOs to all stacks in the system to test how the drivers will run after this.

IMHO another great candidate to be added to Verifier or to checked build is - device object destruction from ObDereferenceObject
without IoDeleteDevice being called due to buggy reference counting. This could be a very useful thing sometimes.

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