One of the most fun things about writing for The NT Insider is the ability to generate comment and controversy around what you write. We exchanged a few emails as a result of last issue’s article Nt vs. Zw - Clearing Confusion On The Native API.
In that article we recommended that driver writers use the Zw variants of the routines so that their kernel mode credentials and buffers are properly handled. This of course assumes that you are servicing a request on behalf of a kernel mode component and are passing in kernel mode buffers. We wanted to emphasize that there are in fact many times when you might need to service a request on behalf of a user mode component, using the supplied user mode credentials and buffers. In these cases, it is much more desirable to use the Nt variant of the system service call because doing so places the onus of checking the user’s parameters on the Windows system service code. Remember, it’s your responsibility to validate buffers passed into a Zw call!
Some folks have gone so far as to suggest that, even though the Nt form of the system service calls aren’t specifically documented (and the prototypes aren’t supplied), they should be the version you use by default. In fact, we tend to agree that this is the most conservative course. This is at least slightly controversial, however, and even our friends up at Microsoft don’t necessarily agree on which approach is best.
Another point we’d like to emphasize has to do with the use of kernel handles. Not only does using kernel handles allow for access to the handles from all process contexts, it also adds increased security. If you do not specify OBJ_KERNEL_HANDLE when creating a handle, the handle is valid in the current process context and accessible from that process. A malicious or buggy application could delete the handle or replace it to point off to something that it should not be able to access. However, as was pointed out in the article and sample code, user mode components have no access to kernel handles so using OBJ_KERNEL HANDLE closes this security hole.