custom handles for usermode

I need to pass a handle/identifier to usermode to be able to track requests. And obviously when a future IOCTL passes back that handle, I need to be sure usermode isn’t up to mischief.

Is there an existing API for this, or should I just maintain a freelist of small integers which I can check against an array of known handles when usermode passes it back to me? If the latter, are there any pitfalls I need to watch out for?

The problem I’m solving here is that usermode will request an SRB (obviously not an exact SRB, but enough information for usermode to service the SRB), and then a short time later usermode will complete the SRB (eg passing back a buffer for a read request). I need to pass usermode an identifier when the SRB is requested, and track that identifier when the SRB is completed.

And to further elaborate, usermode will basically only get read and write requests, as well as pass some device dimensions on startup. I’m not going to allow arbitrary mode pages etc to be sent from usermode.

James

There’s is (ExCreateHandleTable) but it’s unfortunately not documented. Heck, I don’t even know if it’s exported outside the OS.

Peter
OSR

On Fri, Dec 13, 2013 at 2:37 PM, wrote:
> There’s is (ExCreateHandleTable) but it’s unfortunately not documented. Heck, I don’t even know if it’s exported outside the OS.
It doesn’t look like it, at least not on win7.

Kris

>
> Peter
> OSR
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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


Kris

I suppose you will internally have a table of SCSI tasks in the kernel, and the tag would be an index. The usermode can use the task tag. You only need to check that it’s within the table size. Then you’ll validate whether the returned data size is within Expected Data Transfer Length or the task. The usermode will be your SCSI task server.

Instead of only allocating from a freelist of small integers, I tend to prefer handle values that are not reused (or reused less often). An easy way to do this is to generate handles with an embedded cookie value, like an increasing value (or pseudo random sequence) for the upper bits, and an index into a handle table for the lower bits. You can just mask off the lower bits to find the potential slot in a handle table, and the entry in the handle table stores the cookie, which you check for a match when doing handle table operations. This allows the detection of stale handles, and also can prevent a malicious app from guessing what a valid handle may be. If the handle is 64-bits, and you use the bottom 16-bits for the index (64k active handles) you get a 48-bit cookie which will not roll over for a very long time. I also sometimes use a random seed set at driver start for the start of the cookie sequence, so you can have some confidence the handle was created for the current OS boot.

Having unique handle values also allows you to timeout handles, with no chance of a future reuse clash. For kernel code that is giving async requests to user mode code, a timeout is a good defensive strategy.

A variation of this is to split the index into two parts, a table index and a table entry index, like say 8 bits for each. This allows you to dynamically grow the handle table by allocating new 256 entry chunks, with a table index array that either has null or a pointer to the 256 entry chunk.

Free slots are linking into a list.

I also sometimes take some bits in the handle for a type tag, if you have multiple handle types. This allows you to instantly detect if the wrong handle type is being passed, and return an error that specifically means handle type mismatch instead of just invalid handle. It also gives you the option to have one handle table for multiple type of handles. You can also put the type in the table slot instead of the handle value.

The code to do all this is not very big as the only operations are generally allocate, find, and deallocate a handle from the table. Everything is just an array index, so no hash tables or trees needed.

For some uses, like the handle may be sent across a network to be processed by a worker machine, you may want to use a 128-bit GUID handle, which with a high degree of confidence can be unique across machines. On a GUID handle, you can still use the subfield trick to avoid having to do a hash/tree search.

Jan

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of James Harper
Sent: Friday, December 13, 2013 1:25 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] custom handles for usermode

I need to pass a handle/identifier to usermode to be able to track requests. And obviously when a future IOCTL passes back that handle, I need to be sure usermode isn’t up to mischief.

Is there an existing API for this, or should I just maintain a freelist of small integers which I can check against an array of known handles when usermode passes it back to me? If the latter, are there any pitfalls I need to watch out for?

The problem I’m solving here is that usermode will request an SRB (obviously not an exact SRB, but enough information for usermode to service the SRB), and then a short time later usermode will complete the SRB (eg passing back a buffer for a read request). I need to pass usermode an identifier when the SRB is requested, and track that identifier when the SRB is completed.

And to further elaborate, usermode will basically only get read and write requests, as well as pass some device dimensions on startup. I’m not going to allow arbitrary mode pages etc to be sent from usermode.

James


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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