It isn’t as if PsGetProcessId is a heavy-weight function:
nt!PsGetProcessId:
8086ca32 8bff mov edi,edi
8086ca34 55 push ebp
8086ca35 8bec mov ebp,esp
8086ca37 8b4508 mov eax,dword ptr [ebp+8]
8086ca3a 8b8094000000 mov eax,dword ptr [eax+94h]
8086ca40 5d pop ebp
8086ca41 c20400 ret 4
(this from a Server 2003 system I happened to have open in the debugger
anyway.)
PsGetProcessId takes the EPROCESS and pulls a field from it (see
http://msdn.microsoft.com/en-us/library/aa906762.aspx for the argument
list.) That field is the process ID.
EBP+8 is the EPROCESS - you might want to look at this. EAX+94h is the
field in the EPROCESS (from “dt nt!_EPROCESS”):
+0x094 UniqueProcessId : Ptr32 Void
So, the only reasonable conclusion here is that what you have is not a
valid EPROCESS (I like the fact EAX is 0x30. What do you see when you
type “!process”?
Jumping up one level, we can examine FltGetRequestorProcessId:
kd> uf FltGetRequestorProcessId
fltmgr!FltGetRequestorProcessId:
f7242342 8bff mov edi,edi
f7242344 55 push ebp
f7242345 8bec mov ebp,esp
f7242347 ff7508 push dword ptr [ebp+8]
f724234a e8cbffffff call fltmgr!FltGetRequestorProcess
(f724231a)
f724234f 85c0 test eax,eax
f7242351 7408 je fltmgr!FltGetRequestorProcessId+0x19
(f724235b)
fltmgr!FltGetRequestorProcessId+0x11:
f7242353 50 push eax
f7242354 e88d060000 call fltmgr!PsGetProcessId (f72429e6)
f7242359 eb02 jmp fltmgr!FltGetRequestorProcessId+0x1b
(f724235d)
fltmgr!FltGetRequestorProcessId+0x19:
f724235b 33c0 xor eax,eax
fltmgr!FltGetRequestorProcessId+0x1b:
f724235d 5d pop ebp
f724235e c20400 ret 4
This isn’t exactly rocket science either but leads us to
FltGetRequestorProcess:
kd> uf FltGetRequestorProcess
fltmgr!FltGetRequestorProcess:
f724231a 8bff mov edi,edi
f724231c 55 push ebp
f724231d 8bec mov ebp,esp
f724231f 8b4508 mov eax,dword ptr [ebp+8]
f7242322 f60001 test byte ptr [eax],1
f7242325 740b je fltmgr!FltGetRequestorProcess+0x18
(f7242332)
fltmgr!FltGetRequestorProcess+0xd:
f7242327 ff70c4 push dword ptr [eax-3Ch]
f724232a ff15fc3124f7 call dword ptr
[fltmgr!_imp__IoGetRequestorProcess (f72431fc)]
f7242330 eb06 jmp fltmgr!FltGetRequestorProcess+0x1e
(f7242338)
fltmgr!FltGetRequestorProcess+0x18:
f7242332 ff15383224f7 call dword ptr
[fltmgr!_imp__IoGetCurrentProcess (f7243238)]
fltmgr!FltGetRequestorProcess+0x1e:
f7242338 5d pop ebp
f7242339 c20400 ret 4
It either comes from the IRP (IoGetRequestorProcess) or it is the
current process. MY guess is that it comes from the IRP in this case -
pull it off the stack (2nd parameter of the function called by
IopfCallDriver generally, unless it’s been overwritten) and look at the
IRP - I bet you will find that it doesn’t contain a valid thread
pointer. If that’s the case, everything is going to come unraveled
(they check for NULL, but if it isn’t NULL, the check won’t fall into
the “so just get the current process” path.)
Truthfully, this doesn’t look like a bug in your filter from this
information - you don’t control the IRP and you didn’t set up the
fields. It is filter manager’s responsibility to handle this (if it
can) or the caller’s responsibility to not hand filter manager an
improperly set-up IRP or the I/O Manager’s to not return something that
isn’t a valid EPROCESS pointer. It’s going to take a bit more digging
to figure out who should have handled this particular case (and how it
should have been handled - the problem with mitigation is that it
doesn’t eliminate the bug, it just makes it less likely to be observed.
That isn’t necessarily a good thing.)
My suggestion to the filter team would be to broaden the validity check
so that the Irp->Tail.Overlay.Thread needs to be a valid kernel address
(maybe this already happens in the checked build?) Since this is a
union, it is possible someone used it (e.g., in a device queue) but
didn’t initialize it back to zero. That still won’t fix the problem if
it IS inside the kernel address range, though, and ultimately it is the
caller that needs to either zero down that field or set it to the
current thread. Ah, but that probably isn’t documented so we can blame
the documentation team for the problem.
So this points back again to the IRP in question - find it, dump it and
see what is in that field. But I don’t see anything here that says it
is a bug in your driver’s logic.
Tony
OSR