Skipping IRP stack locations and driver verifier problems

Lukas Rypacek wrote:

An experienced driver developer from Microsoft has suggested to
me that we should check for the Verifier presence and only call
IoSkipCurrentIrpStackLocation( ) if Verifier is not loaded.

Brilliant. Maybe we can find other “solutions” by replacing “Verifier” with “DTM”…

Chris Aseltine wrote:

Brilliant. Maybe we can find other “solutions” by replacing “Verifier” with
“DTM”…

True. On the other hand, it is a pitty not to use Verifier’s IO verification for your TDI driver at all. Knowing about this bug and dealing with it (e.g. with this sort of DEBUG trick) can actually help you more. Or not?


An experienced driver developer from Microsoft has suggested to me that we
should check for the Verifier presence and only call
IoSkipCurrentIrpStackLocation( ) if Verifier is not loaded.


I have great trouble believing that this was actually suggested by someone
even remotely familiar with how the DV monitors IRP progress.

First of all, you must skip the location if you are not going to use it.
Otherwise, you are just wasting an I/O Stack Location and you have already
determined that in this case, there are not enough. This is just going to
make it bugcheck anyway.

Second, I seriously doubt that DV “… uses the stack location your driver
would otherwise use (but didn’t)…” since DV is very good about not
changing anything about the IRP that a driver could otherwise see. This
would be a very visible thing for a driver to see. It has always been my
understanding that DV hides it’s context for IRP away in a safe spot away
from prying eyes.

And yes, NETBT, AFD, and RASPPTP are all rather poor TDI clients. Some use
fixed size IRPs of a maximum value; others never bother to call
IoGetRelatedDeviceObject() and send IRPs to the bottom of the stack; some
can’t be bothered to even allocate an IRP with more than two stacks (one for
itself, one for TCPIP). The whole thing is a rather sad state of affairs
when you mix in the number of bad TDI filters that have been written over
the years.

That is what makes it all fun, wouldn’t ya say?

Good Luck,
Dave Cattley
Consulting Engineer
Systems Software Development

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@asw.cz
Sent: Wednesday, October 08, 2008 5:35 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Skipping IRP stack locations and driver verifier
problems

Hi, I don’t know if the original topic is already lost in rant, but I have
also seen this netbt bug and I assume everyone who tried to deploy a TDI
filter must have already dealt with it. It can be avoided by issuing a newly
allocated IRP with enough stack locations instead of the short one, or
skipping the location, if that is the option.

As I understand it, skipping the current stack location is OK, however, when
driver verifier is enabled, is uses the stack location your driver would
otherwise use (but didn’t) for its own completion routine. In effect, even
if your driver would call IoSkipCurrentIrpStackLocation( ), that stack
location would be used for driver verifier. From this point of view it is
not a false positive, since the IRP is truly too short to run with Verifier
:slight_smile:

An experienced driver developer from Microsoft has suggested to me that we
should check for the Verifier presence and only call
IoSkipCurrentIrpStackLocation( ) if Verifier is not loaded.

Lukas R.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

— On Wed, 10/8/08, David R. Cattley wrote:
> From: David R. Cattley

> First of all, you must skip the location if you are not
> going to use it.

Eh? I think I could just IoCopy* if I don’t skip.

> Otherwise, you are just wasting an I/O Stack Location

Worse yet, the lower driver sees uninitialized stack which would draw beautiful whites on blue, because IoCallDriver advances stack before handing the irp to the lower.


Calvin Guan
Broadcom Corp.
Connecting Everything(r)

__________________________________________________________________
Instant Messaging, free SMS, sharing photos and more… Try the new Yahoo! Canada Messenger at http://ca.beta.messenger.yahoo.com/

Calvin,

Of course you are correct! If enough stack locations existed you could just
copy the current to the next and call IoCallDriver. The OP is in the
situation, however, where the number of I/O stack locations in the IRP are
not sufficient. That is why I emphasized *must* skip.

I do think it rather pointless, however, if one just copies the stack
location and does not set a CRTN. What is accomplished other than burning a
IOSL?

Maybe I am too naive to see the subtly of doing this. I it just seems a
waste of an IOSL to me…

Cheers,
-dave

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Calvin Guan
Sent: Wednesday, October 08, 2008 9:55 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Skipping IRP stack locations and driver verifier
problems

— On Wed, 10/8/08, David R. Cattley wrote:
> From: David R. Cattley

> First of all, you must skip the location if you are not
> going to use it.

Eh? I think I could just IoCopy* if I don’t skip.

> Otherwise, you are just wasting an I/O Stack Location

Worse yet, the lower driver sees uninitialized stack which would draw
beautiful whites on blue, because IoCallDriver advances stack before handing
the irp to the lower.


Calvin Guan
Broadcom Corp.
Connecting Everything(r)

__________________________________________________________________
Instant Messaging, free SMS, sharing photos and more… Try the new Yahoo!
Canada Messenger at http://ca.beta.messenger.yahoo.com/


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> From: David R. Cattley
> Subject: RE: [ntdev] Skipping IRP stack locations and driver verifier problems
> I do think it rather pointless, however, if one just copies
> the stack
> location and does not set a CRTN. What is accomplished
> other than burning a
> IOSL?

You’re right Dave, it doesn’t do anything useful. I thought the problem was “DV asserts if and only if I call IoSkipXxx”.

If the problem is lack of stack location, if I’m desperate and if I’m just doing it for fun, I would attempt to switch IO stack location on its way down and switch back in the completion routine. (There are a lot of IFs here:))

Calvin

__________________________________________________________________
Get the name you’ve always wanted @ymail.com or @rocketmail.com! Go to http://ca.promos.yahoo.com/jacko/

> even if your driver would call IoSkipCurrentIrpStackLocation( ), that stack location would be

used for driver verifier.

Not really…

The very term ‘skip’ is a bit misleading here - it would be better to say “reuse”. Although the very name IoSkipCurrentIrpStackLocation( ) somehow suggests that current stack location gets skipped so that you
proceed to the next one, in actuality this is not what happens -instead, stack pointer gets decremented, subsequent call to IoCallDriver() advances it, and, as a result, when the lower driver’s dispatch routine gets invoked, stack pointer is at exactly the same position it used to be at when your driver’s dispatch routine got invoked. In other words, all unused stack locations are ahead of the stack pointer, rather than behind it. Therefore, if verifier tries to make any use of a stack location that you skip with IoSkipCurrentIrpStackLocation( ), it is going to screw up lower driver’s operations…

Anton Bassov

Huh?

I don’t understand your point, Anton. I THINK the analysis presented up to this point was correct, and reasonably complete. What are you trying to add?

When you have I/O Verification enabled for Driver Verifier, Verifier (itself) needs an I/O completion callback. So, even if you call IoSkipCurrentIrpStackLocation(), Verifier does the equivalent of IoCopyCurrentIrpStackLocationToNext().

That’s the whole point here, as I understand it.

While I agree that IoSkipCurrentIrpStackLocation is poorly named, it’s just one of a number of badly named I/O functions that come from an era where there was a lot of work going on and not nearly enough attention was paid to what the functions were named…

Peter
OSR

> I don’t understand your point, Anton. I THINK the analysis presented up to this point was correct,

and reasonably complete. What are you trying to add?

Actually, I am just trying to understand how it does things, i.e. WHY it all happens and what it does wrong…

When you have I/O Verification enabled for Driver Verifier, Verifier (itself) needs
an I/O completion callback. So, even if you call IoSkipCurrentIrpStackLocation(),
Verifier does the equivalent of IoCopyCurrentIrpStackLocationToNext().

Please note that both IoCopyCurrentIrpStackLocationToNext() and IoSkipCurrentIrpStackLocation() are just macros, rather than kernel exports. Therefore, it has no chance to do anything before you call IoCallDriver(), so that must be playing its tricks on IRP when you pass it down the stack, i.e. simply hooks IoCallDriver() in your driver’s IAT on order to monitor outgoing packets, and your driver’s Dispatch routine in order to monitor incoming ones… .

If you register your completion routine and IoCopyCurrentIrpStackLocationToNext() , its task of registering its own completion routine is pretty easy - this involves nothing more than just hooking your routine by changing function pointer in IRP. However, if you just skip a stack location, it has, indeed, make its own equivalent of IoCopyCurrentIrpStackLocationToNext(), so that it must be able to make a distinction between these two scenarios by monitoring stack pointer. Apparently, there must be some bug in this part of Verifier’s code…

While I agree that IoSkipCurrentIrpStackLocation is poorly named…

As you can see it yourself, in actuality, the long meaningful IoSkipCurrentIrpStackLocation() may be as misleading as some cryptic skip_loc() or any other name that you have to decypher…

Anton Bassov

I’m not going to bite on your trolling, but there IS no bug in Verifier in this instance.

Did you actually take the time to read the docs on these functions and read the source because they’re macros, or are you just going by intuition and feel? I know that doing your homework before you rant/troll isn’t necessarily your style.

When you enable I/O Verification, Verifier needs an I/O Stack Location for a completion routine. It won’t have that if your driver “skips” the stack location by calling IoSkipCurrentIrpStackLocation. Ergo, Verifier uses an I/O Stack Location (thus doing the equivalent of IoCopyCurrentIrpStackLocationToNext) even in the case when your driver indicates that the system should re-use the current one (by calling IoSkipCurrentIrpStackLocation).

Not hard to understand, I don’t think.

I’m out of this thread, but do feel free to rant or troll further. Maybe you’d like to provide an extended analysis of the names of every Windows kernel function and whether, in your opinion, it is or is not well and sufficiently economically named. Perhaps provide a table of names that you’d prefer for each? Old Name, New Name, Short Name… I’m sure that’d be interesting to a lot of folks on this list.

Peter
OSR

> there IS no bug in Verifier in this instance.

Why does the properly-written driver crash then???

Did you actually take the time to read the docs on these functions and read the source
because they’re macros,or are you just going by intuition and feel

Did you actually take the time to read my post which says that, unlike IoCallDriver(), both IoCopyCurrentIrpStackLocationToNext() and IoSkipCurrentIrpStackLocation() are just macros, rather than kernel exports, or are you just going by intuition and feel (i.e. intuitively feel that I am about to criticize MSFT for something)??? Although you do have a good reason to feel so, based upon my numerous posts, on this particular occasion you are plainly wrong…

I know that doing your homework before you rant/troll isn’t necessarily your style.

Well, I am afraid in this respect I am just a kid compared to you - as I can see, you have really a supra-natural ability to argue with posts without actually even reading them…

When you enable I/O Verification, Verifier needs an I/O Stack Location for a completion routine.
It won’t have that if your driver “skips” the stack location by calling IoSkipCurrentIrpStackLocation.
Ergo, Verifier uses an I/O Stack Location (thus doing the
equivalent of IoCopyCurrentIrpStackLocationToNext) even in the case when your driver
indicates that the system should re-use the current one (by calling IoSkipCurrentIrpStackLocation).

Actually, this is exactly what I said in my post, but, as we have already established, you did not even bother yourself with reading it - instead, you went straight to accusations. The only thing I am speaking about is the moment when it does the above - I believe it must be the one when you call IoCallDriver()…

Perhaps provide a table of names that you’d prefer for each?

Look - you are the only one who, for the reasons better known to himself, speaks about names and naming conventions. In case if I wanted to troll, I would rather choose something more substantial than that. Apparently, you just missed the sarcasm of my statement - just few days ago you attacked UNIX naming convention (which, is, indeed, inconvenient - I don’t argue about it), so that my statement was meant just to demonstrate how insignificant this topic is…

Anton Bassov

> Look - you are the only one who, for the reasons better known to himself,

speaks about names and naming conventions. In case if I wanted to troll, I
would rather choose something more substantial than that. Apparently, you
just missed the sarcasm of my statement - just few days ago you attacked
UNIX naming convention (which, is, indeed, inconvenient - I don’t argue
about it), so that my statement was meant just to demonstrate how
insignificant this topic is…

I breaking all the rules of thread hijacking, sorry, well not so sorry :-(.

Here is one thing I want to point you out Anton, and it has nothing to do
with you or Peter or anyone else…

Well, there are a lot of things to worry about naming, and it is a big
part of software… You will develop with short name, but people who are
behind you line up to maintain ( hence eating away most of the budget)
really need those naming right along with lots of other stuff… It is
very very significant …

As I said before, I deal with over a million line of source ( C, C++, some
ASM ) open and closed source… And I can tell how hard it is to manage
these when naming conventions are bad…

Once again, this is no flaming. But for commercial product, do not
encourage those cryptic names etc… And please note, whoever does their
job dealing with it is more important than who creates the mess …

-pro

> Well, there are a lot of things to worry about naming, and it is a big part of software…

Well, by “insignificant” I meant “insignificant as a point to argue about”…

You will develop with short name, but people who are behind you line up to maintain

Well, I definitely would not develop it with a short name when writing Windows code, and vice versa…

I deal with over a million line of source ( C, C++, some ASM ) open and closed source…
And I can tell how hard it is to manage these when naming conventions are bad…

I would say the best thing to do here is just to stick to the generally accepted convention of the OS you write your code for -even if you don’t like it. If you combine it with proper comments, it seems to be just a wonderful way to stay friends with those who maintain/integrate/etc your code…

Anton Bassov

OK then, for a moment I just wanted to flush out my thoughts …

Now make sense, so … end of offtopic…

-pro

On Thu, Oct 9, 2008 at 2:40 PM, wrote:

> > Well, there are a lot of things to worry about naming, and it is a big
> part of software…
>
> Well, by “insignificant” I meant “insignificant as a point to argue
> about”…
>
> > You will develop with short name, but people who are behind you line up
> to maintain
>
> Well, I definitely would not develop it with a short name when writing
> Windows code, and vice versa…
>
> > I deal with over a million line of source ( C, C++, some ASM ) open and
> closed source…
> > And I can tell how hard it is to manage these when naming conventions are
> bad…
>
> I would say the best thing to do here is just to stick to the generally
> accepted convention of the OS you write your code for -even if you don’t
> like it. If you combine it with proper comments, it seems to be just a
> wonderful way to stay friends with those who maintain/integrate/etc your
> code…
>
>
>
> Anton Bassov
>
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

To OP: I also met this problem in past:

http://msmvps.com/blogs/v_scherbina/archive/2008/01/16/driver-verifier-iomanager-violation-in-windows-server-2003-sp2-with-latest-updates-on.aspx

I sent a question to WNDP, and here is a reply I recieved from them:

date 5 février 2008 18:14
objet FW: (Windows Core Networking) : an issue with Server 2003 SP2

>
I had a brief look at the verifier code which gives this break, it could be
a little over zealous. It seems to break if there are <= 2 stack locations
left in the Irp. This shouldn’t be a big issue as it won’t happen without
verifier.

He can probably increment the DeviceObject->StackSize by 2 as a work
around to the problem.

> Please also ask him if setting a completion routine in the Irp solves his
> problem.

Thanks
Praveen
<<

HTH,


Volodymyr, blog: http://www.shcherbyna.com/
(This posting is provided “AS IS” with no warranties, and confers no
rights)

wrote in message news:xxxxx@ntdev…
>> Look - you are the only one who, for the reasons better known to himself,
>> speaks about names and naming conventions. In case if I wanted to troll,
>> I
>> would rather choose something more substantial than that. Apparently, you
>> just missed the sarcasm of my statement - just few days ago you attacked
>> UNIX naming convention (which, is, indeed, inconvenient - I don’t argue
>> about it), so that my statement was meant just to demonstrate how
>> insignificant this topic is…
>
> I breaking all the rules of thread hijacking, sorry, well not so sorry
> :-(.
>
> Here is one thing I want to point you out Anton, and it has nothing to do
> with you or Peter or anyone else…
>
> Well, there are a lot of things to worry about naming, and it is a big
> part of software… You will develop with short name, but people who are
> behind you line up to maintain ( hence eating away most of the budget)
> really need those naming right along with lots of other stuff… It is
> very very significant …
>
> As I said before, I deal with over a million line of source ( C, C++, some
> ASM ) open and closed source… And I can tell how hard it is to manage
> these when naming conventions are bad…
>
> Once again, this is no flaming. But for commercial product, do not
> encourage those cryptic names etc… And please note, whoever does their
> job dealing with it is more important than who creates the mess …
>
> -pro
>
>

I currently believe Verifier was well-intentioned here, but overaggressive. It was trying to point out that *if one of the drivers on this device stack will change its design in the future, and not Skip the stack location anymore*, then the IRP will run out of stack locations. That scenario is conceivable but some folks pointed out that they will *never* change their IoSkipCurrentIrpStackLocation design, therefore Verifier was overaggressive in their particular scenario. Thanks to those of you who talked with me about this at the DDC!

So we decided to remove this check from future OS versions. On older OS versions, I believe users have to continue after this kernel debugger break, or disable the Enhanced I/O Verification if they are blocked by it.

Please feel free to follow-up on verifier @ microsoft.com about this issue or anything else related to Verifier.

Thanks,
Dan