There are a lot of (potential) problems with this. You should be glad that
DV isn’t allowing you to ignore and continue, because it’s a real problem
and not just synthetic debugger grouchiness.
First of all, think about your code. You’re testing whether a pointer to a
single field (Signature) is valid, and then assuming that the rest of the
structure is valid. PointerToStruct could be aligned so that Signature lies
on a valid page, but the rest of the fields do not. So your “IsGood” test
has only verified the accessibility of a single structure.
Second, you have assumed that the validity of the pointer does not change
over time. Unless you have taken steps to insure that the page(s) under
that PointerToStruct points to cannot be paged out, this is a dangerous
assumption that is guaranteed to fail at some time. This is not an
artificial concern; it is a serious bug that will eventually occur, and will
be difficult to reliably reproduce because it involves a race condition.
Basically, you can test the pointer, find that it is good, time passes, the
pointer *becomes* invalid (not because it changed, but because what it
points to has changed), and then you will dereference the pointer because
you previously found it to be good, and then you crash.
Next, you must be very careful about process contexts. Pointers to
user-mode data are only meaningful in a specific process context. If you
know for certain that your driver will always be executing in the context of
the process that issued the request, then you can use user-mode pointers.
But you STILL can’t use them without some very serious precautions.
Read up on ProbeForRead, ProbeForWrite, MmProbeAndLockPages, and similar
topics.
What buffering mode are you using for your IOCTLs? If you are using
BUFFERED_IO, then you don’t have to worry about a lot these issues. The
kernel allocates pool for you, copies data from user-mode to the pool (if
InputBufferLength != 0), submits the IRP to your driver, waits for it to
complete, and copies data from pool to user-mode (if OutputBufferLength !=
0). All of the memory accesses are validated by the I/O manager, and by the
time the data reaches your driver, you can rely on the presence and
stability of the buffer. You still need to validate the InputBufferLength
and OutputBufferLength, and you still need to deal with the *contents* of
the buffers (which can be anything at all – never trust anything you
receive from user-mode). BUFFERED_IO is typically used for “small”
requests, or for requests where time is not critical. Still, don’t
underestimate the safety and performance of buffered I/O until you’ve
measured it and truly found the time spent during
allocation/copy/deallocation to be a significant impact on your design.
If you are using DIRECT_IO, then you need to deal with MDLs. If you are
using METHOD_NEITHER, then you are dealing with raw, uninterpreted user-mode
pointers, and you must be extremely cautions. In general, METHOD_NEITHER
should be avoided, until you have proved to yourself that it is the only way
to accomplish your goals.
You may know some of this already, of course, but I can’t tell from the
short snippet you’ve posted. Also, you’re more likely to get a decent
response in NTDEV – the WinDbg list is for questions related to the
debugger itself, not driver correctness.
– arlie
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Greg Pearce
Sent: Tuesday, March 14, 2006 1:22 PM
To: Kernel Debugging Interest List
Subject: [windbg] Access Violation and Verifier under WinDBG
I have an FSD that talks to a user mode app using ioctls. When the FSD gets
a buffer back from the user mode app, it is tested for validity by trying to
touch it in a try/except clause like this:
try
{
if ( PointerToStruct->Signature eq OUR_SIGNATURE )
{
IsGood = TRUE;
}
}
except(EXCEPTION_EXECUTE_HANDLER)
{
IsGood = FALSE;
}
This works ok, unless I run under driver verifier. This exception is
expected sometimes, and when under verifier, the exception fires and I can’t
get the debugger to resume and ignore this error.
I tried “go handled” but that didn’t work - the debuggee was unresponsive
and the mouse oculdn’t move etc. The debuggee looked like it was still
halted.
What am I doing wrong here?
Thanks in advance for any assistance.
You are currently subscribed to windbg as: xxxxx@stonestreetone.com To
unsubscribe send a blank email to xxxxx@lists.osr.com