Possible VERIFIER bug (Vista x64) when IRQL checking enabled

Perhaps this is old news (though I cannot find a statement to that effect) but I have hit an issue when IRQL and Deadlock checking are enabled on Vista SP2 x64 (free). Essentially the detour through nt!VerifierKeAcquireSpinLockRaiseToDpc causes the R14 register to get clobbered.

The code in my driver is the following:

fffffa6002caf23b 498d8e80000000 lea rcx,[r14+80h] fffffa6002caf242 ff1510aeffff call qword ptr [xxxxxxxxxx!_imp_KeAcquireSpinLockRaiseToDpc (fffffa60`02caa058)]
fffffa60`02caf248 498b8e88000000 mov rcx,qword ptr [r14+88h]
fffffa60`02caf24f 4885c9 test rcx,rcx

With verifier enabled the “mov rcx,qword ptr [r14+88]” causes an exception because r14 has 0x0 in it.

Yet clearly R14 was perfectly reasonable and holding the valid address of my NPPool allocated context block just prior to the call into nt!KeAcquireSpinLockRaiseToDpc() else the kernel would have blow up because I gave it a spinlock address of 0x080.

So the only thing I can conclude is that the detour through verifier clobbered r14.

Of course when I run without verifier across this same section of code r14 is preserved as expected as a NV register.

has anyone else seen this?

Cheers,

Dave Cattley

Can’t say I’ve seen this. Of course, I can’t say I’ve run anything on Vista of ANY service pack… like, probably, ever. Does the same problem occur on S08 SP2?? We *have* tested on that here at OSR, certainly.

Wow… This would HAVE to be a pretty big bug in the compiler if what you infer is true, don’t you think? The DV code is written in C. R14 is a non-volatile register. If what you say is true either R14 isn’t being saved properly, or something’s overwriting the stack where R14 *was* saved.

One would think somebody would have seen this before… given that it’s a crash it’d be pretty hard to miss. Of course, KeAcquireSpinLockRaiseToDpc isn’t the MOST common function called. But, still.

Did you trace/disassemble the code through DV to see R14 being hammered, by chance? Maybe throw IDA at it?

Peter
OSR
@OSRDrivers

Are you running in a VM or in a physical machine?

> Are you running in a VM or in a physical machine?

It is a physical machine. And since it does not crash immediately on boot with the first use of KeAcquireSpinLock() because I have Verifier enabled for all drivers I am convinced it is something that just goes wrong given the state of the machine when my driver calls the detoured routine instead of it being fundamentally broken in the Verifier code.

Sadly I cannot move to another OS as my user is reporting the real problem I am hunting on Vista SP2. I would really like to just say “upgrade to any OS after that” as an answer :slight_smile:

Thanks,

Dave Cattley

Is there a possibility that you gave away a stray pointer to a stack variable in a function that you called before that, and the location where R14 was saved got garbled?

> Is there a possibility that you gave away a stray pointer to a stack variable in a function

that you called before that, and the location where R14 was saved got garbled?

I don’t think so. Saving R14 is the responsibility of the called routine not my routine doing the calling. It would be saved (only if needed) in a frame of the callee.

Thanks,

Dave Cattley

>It would be saved (only if needed) in a frame of
the callee.

The stray pointer could point to the currently vacated stack position. Running with verifier may cause the call stack to go deeper, where that pointer could now have pointed to the location where R14 is saved.

> The stray pointer could point to the currently vacated stack position.

Running with verifier may cause the call stack to go deeper, where that

pointer could now have pointed to the location where R14 is saved.

Ah! I get it. Thanks for being patient.

I will check for that possibility. The only pointer I am passing into the called context is the pointer to the spinlock itself but indeed if that is bogus and happens to point into unused stack then the condition you suggest could occur.

I will definitely be applying that analysis.

Thanks,

Dave Cattley

The stray pointer could be to an object created on the stack which was then linked to a list.

Step over some successful call and find at what offset R14 is saved (you may zero the stack to see how far it was used by the call).
Then before such call in the same call context that was having the crash, inspect the stack location where R14 would get saved. You may figure the type of object pointed by.