Premature IRP completion causing BSOD (?)

Hi,

For the last couple of weeks I have been experimenting with writing
file system filter drivers for windows 2000. For testing purposes I
implemented a dispatch routine in my filter driver that would
“complete” (fail) all incoming IRPs.

This is basically what I do:

IoSetCompletionRoute(irp, routine, FALSE, FALSE, FALSE);

IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;

IoCompleteRequest(irp, IRP_NO_INCREMENT);

return STATUS_INVALID_REQUEST;

The reason I implemented the dispatch routine like this is because the
filter driver I will eventually be writing will fail some IRPs due to
ACLs or other circumenstances and I wanted to see how the
kernel would react to this.

Most of the time everything works as expected, but sometimes I get a
BSOD with a KERNEL_STACK/DATA_INPAGE_ERROR. Further
investigation using softice reveals that the BSOD seems to happen only
when I complete an IRP coming from the VMM (backtrace shows
mm/rtl*Memory functions) at APC_LEVEL.

My Question(s):

Is the BSOD to be “expected” when i fail an IRP coming from the VMM?

What is the correct way to fail / complete such an IRP?

I hope some of the people here can help me out,

Kind Regards,

Joost Pol

Hello? You tell MM that an inpage error fails and you are surprised when it
barfs?

Kernel stacks and data are paged out. When they page back in, reporting an
error is an unrecoverable error. If you don’t want to crash the OS, don’t
fail such reads.

You don’t give us an indication of the goal here, so there isn’t much
guidance I can give, but I must admit I am not surprised it dies for you!

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: Joost Pol [mailto:xxxxx@pine.nl]
Sent: Wednesday, September 17, 2003 10:30 PM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] Premature IRP completion causing BSOD (?)

Hi,

For the last couple of weeks I have been experimenting with writing
file system filter drivers for windows 2000. For testing purposes I
implemented a dispatch routine in my filter driver that would
“complete” (fail) all incoming IRPs.

This is basically what I do:

IoSetCompletionRoute(irp, routine, FALSE, FALSE, FALSE);

IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;

IoCompleteRequest(irp, IRP_NO_INCREMENT);

return STATUS_INVALID_REQUEST;

The reason I implemented the dispatch routine like this is because the
filter driver I will eventually be writing will fail some IRPs due to
ACLs or other circumenstances and I wanted to see how the
kernel would react to this.

Most of the time everything works as expected, but sometimes I get a
BSOD with a KERNEL_STACK/DATA_INPAGE_ERROR. Further
investigation using softice reveals that the BSOD seems to happen only
when I complete an IRP coming from the VMM (backtrace shows
mm/rtl*Memory functions) at APC_LEVEL.

My Question(s):

Is the BSOD to be “expected” when i fail an IRP coming from the VMM?

What is the correct way to fail / complete such an IRP?

I hope some of the people here can help me out,

Kind Regards,

Joost Pol


You are currently subscribed to ntfsd as: xxxxx@osr.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Re,

On Thu, Sep 18, 2003 at 11:33:27AM -0400, Tony Mason wrote:

Hello? You tell MM that an inpage error fails and you are surprised when it
barfs?

Thanks for clearing that up, sounds obvious indeed.

You don’t give us an indication of the goal here, so there isn’t much
guidance I can give, but I must admit I am not surprised it dies for you!

The goal was to determine how to handle ‘failure’ in my filter driver
dispatch routine. Its clear to me now that you just dont want to
complete/fail any requests coming from the VMM at all.

But it remains a bit unclear to me how to prevent failure at all times.

For example; How do I prevent failing/completing a request from the VMM
when my driver is detaching? During detach I first acquire a resource
that is shared (exclusive) with the dispatch routine, then I wait for
pending IRPs to complete and finally perform the IoDetachDevice etc.

During the detach, when I am holding the resource, there is no safe
way to forward the incoming IRPs to the underlying driver. So I
(have) to fail/complete them.

What happens when one of those requests is from the VMM?

I hope that made sense to anyone :confused:

Kind regards,

Joost Pol


Service Provider :: Pine Digital Security :expressionless: www.pine.nl || +31 (0)70 311 10 10
:: PGP id 0xF360BB93 fpr ABED 303C 0120 E057 633A 1CB1 D236 C82A F360 BB93 ::

Joost Pol wrote:

Re,

On Thu, Sep 18, 2003 at 11:33:27AM -0400, Tony Mason wrote:

>Hello? You tell MM that an inpage error fails and you are surprised when it
>barfs?

Thanks for clearing that up, sounds obvious indeed.

>You don’t give us an indication of the goal here, so there isn’t much
>guidance I can give, but I must admit I am not surprised it dies for you!

The goal was to determine how to handle ‘failure’ in my filter driver
dispatch routine. Its clear to me now that you just dont want to
complete/fail any requests coming from the VMM at all.

But it remains a bit unclear to me how to prevent failure at all times.

For example; How do I prevent failing/completing a request from the VMM
when my driver is detaching? During detach I first acquire a resource
that is shared (exclusive) with the dispatch routine, then I wait for
pending IRPs to complete and finally perform the IoDetachDevice etc.

You don’t have to worry about this, the system will make sure it only
tells you to detach when it’s safe. EXCEPT in some cases with FastFat
pre-XP: read this thread for details:

http://www.osronline.com/lists_archive/ntfsd/thread1323.html


Nick Ryan (MVP for DDK)

Your architecture is broken. Divide your driver into to pieces:

  • A piece that ALWAYS forwards. This becomes the non-removable component.
  • A piece that can be loaded/unloaded. This becomes the removable
    component.

Build the non-removable component to handle the various states gracefully.
Then you never need to fail any request.

FYI: filter drivers are not generally unloadable. Try (for instance)
loading filemon on the system after your filter, then unload. There is no
safe way to ever do that…

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: Joost Pol [mailto:xxxxx@pine.nl]
Sent: Thursday, September 18, 2003 12:38 PM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] RE: Premature IRP completion causing BSOD (?)

Re,

On Thu, Sep 18, 2003 at 11:33:27AM -0400, Tony Mason wrote:

Hello? You tell MM that an inpage error fails and you are surprised when
it
barfs?

Thanks for clearing that up, sounds obvious indeed.

You don’t give us an indication of the goal here, so there isn’t much
guidance I can give, but I must admit I am not surprised it dies for you!

The goal was to determine how to handle ‘failure’ in my filter driver
dispatch routine. Its clear to me now that you just dont want to
complete/fail any requests coming from the VMM at all.

But it remains a bit unclear to me how to prevent failure at all times.

For example; How do I prevent failing/completing a request from the VMM
when my driver is detaching? During detach I first acquire a resource
that is shared (exclusive) with the dispatch routine, then I wait for
pending IRPs to complete and finally perform the IoDetachDevice etc.

During the detach, when I am holding the resource, there is no safe
way to forward the incoming IRPs to the underlying driver. So I
(have) to fail/complete them.

What happens when one of those requests is from the VMM?

I hope that made sense to anyone :confused:

Kind regards,

Joost Pol


Service Provider :: Pine Digital Security :expressionless: www.pine.nl || +31 (0)70 311 10
10
:: PGP id 0xF360BB93 fpr ABED 303C 0120 E057 633A 1CB1 D236 C82A F360 BB93
::


You are currently subscribed to ntfsd as: xxxxx@osr.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

> IoSetCompletionRoute(irp, routine, FALSE, FALSE, FALSE);

IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;

IoCompleteRequest(irp, IRP_NO_INCREMENT);

return STATUS_INVALID_REQUEST;

Throw IoSetCompletionRoute away. This call is used only before IoCallDriver,
not before IoCompleteRequest.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com