ObOpenObjectByPointer and ObGetObjectSecurity

Hi all,

Environment:
(OS versions I have seen this issue on are Windows 2000 SP4 plus hotfixes,
Windows XP Sp2 and Win2003 SP1)
Issue:
I issue a request to ObOpenObjectByPointer (with argument kernelMode) to
obtain a handle for an open file residing on a network share.
(The network mount file has previously been opened with READ_CONTROL and
ACCESS_SYSTEM_SECURITY.)
The function internally calls ObGetObjectSecurity which returns
STATUS_INVALID_USER_BUFFER, which in turn is returned from
ObOpenObjectByPointer.

I have found out why this occurs on a network mount but not when the
fileobject represents a file on a local disk:

The ObGetObjectSecurity function issues an IRP_MJ_QUERY_SECURITY (infact
two requests: one to return the size of the buffer; the second with the
allocated buffer to get the data) to the file system below, the IRP has a
requestor mode set to “UserMode” and not KernelMode and NTFS passes the
kernel buffer (a paged pool allocated buffer, tag ObSq) into
SeQuerySecuritydescriptorInfo, without any obvious prior checks by Ntfs on
the buffer. (I assume reasons of synchronous processing mean it does not
need to use an MDL and lock it, and exceptions will be caught it its
exception handler.)
The security function succeeds and the IRP is completed and the
ObGetObject Security returns successfully.
Incidentally, the file on the local disk has not been opened with
READ_CONTROL and ACCESS_SYSTEM_SECURITY access but still succeeds, is that
a bug? (Since the IRP requestor mode is set to UserMode and
ExGetPreviousMode returns UserMode, even though the request is generated
internally by the kernel with kernel data buffers.)

However, in the case of the redirector and network mount file, mrxsmb.sys,
in its handler for query security, allocates an MDL then probes and locks
the buffer by calling MmProbeAndL:ockPages. Here it passes in the argument
UserMode for the MDL which is actually a kernel paged pool buffer. The Mm
routines raises an exception and the IRP is completed with the status
STATUS_INVALID_USER_BUFFER.

When my filter sees the query security request destined for the network
volume, now modifies the IRP requestor mode to be kernel mode, the IRP
completes successfully.

I really don’t like this “tweaking the irp workaround” and would rather
have a good solution to ensure ObOpenObjectByPointer works for network
files.
Is this a genuine bug, if so, has it been addressed? Does anyone have any
explanations or run into this issue already?
Or better solutions to obtain a handle from a file object on a network
file? Or am I missing something obvious?

Thanks in advance.
Steve

> However, in the case of the redirector and network mount file, mrxsmb.sys,

in its handler for query security, allocates an MDL then probes and locks
the buffer by calling MmProbeAndL:ockPages. Here it passes in the argument
UserMode for the MDL which is actually a kernel paged pool buffer. The Mm
routines raises an exception and the IRP is completed with the status
STATUS_INVALID_USER_BUFFER.

Oh yes, I see. NT4’s FASTFAT has the same issue for FSCTL_GET_VOLUME_BITMAP.

Allocate the memory in user addresses of the System process from
Ex/IoQueueWorkItem callback. This is done using ZwCreateSection without a file
and then ZwMapViewOfSection.

Then specify this memory to the “query security” call (which must be sent from
the Ex/IoQueueWorkItem callback). Then RltCopyMemory it to the kernel space
under the __try/__except block, again from Ex/IoQueueWorkItem callback.

This should work from NT4 and up to Vista (one of our guys tried this on Vista
and it worked, anyway it surely works OK on 2003 R2 SP1).

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