Windows 7 driver verifier can do a DRIVER_VERIFIER_DETECTED_VIOLATION (0xC4) bugcheck with parameter 1 (violation type) set to 0xf6. The top of stack may look something like the following

nt!KeBugCheckEx+0x1e
nt!VerifierBugCheckIfAppropriate+0x32
nt!VfCheckUserHandle+0x15f
nt!ObReferenceObjectByHandleWithTag+0x136
nt!ObReferenceObjectByHandle+0x21
nt!ObpLookupObjectName+0x9a
nt!ObOpenObjectByName+0x159

This new subclass of violation, comes as part of Security Checks1 settings which is new to Windows 7 Driver Verifier. This can be turned on, if you go to the individual settings screen [Select a task->Create custom settings (for code developers)->Select individual settings from a full list]. It is also included when you choose Standard Settings [Select a task->Create standard settings or Select a task->Create custom settings (for code developers)->Enable predefined settings:->Standard settings].

The bugcheck may trigger when a handle that is visible to user mode is accessed in kernel mode. A user mode handle is a handle that is meant for access from user-mode and does not have OBJ_KERNEL_HANDLE attribute set. According to Windows 7 Verifier whitepaper, this is part of new verifier checks that detect "incorrect references to user handles from kernel drivers". For example if  a driver calls ObReferenceObjectByHandle on a user-mode handle, directly or indirectly (ie. calls a ZwXXX or PsXXX call which calls ObReferenceObjectByHandle) with AccessMode set to KernelMode, Windows 7 Driver Verifier may decide to bugcheck with subclass 0xf6.

If a driver forgot to specify OBJ_KERNEL_HANDLE when creating a handle, it will end up creating a user-mode handle which in most cases is bad because user-mode code can now access the object than it may or may not have had access to otherwise. Driver Verifier intends to catch those scenarios by these checks. However if a driver was indeed intending to create a handle so it can be used in user-mode (think of a service provided by driver or an event to communicate with user mode) or modify/query a user-mode handle (think a diagnostics driver attempting to get object type of all handles in  a process), it will be caught by Verifier as well.2 After all drivers are there to do stuff for user-mode and handles and objects are fundamental to getting many things done in Windows.

The whitepaper further elaborates on a second class of problems Verifier intends to catch by this check.

Receiving a handle from an application and referencing it blindly as KernelMode. This action is incorrect because the reference succeeds regardless of the access that was granted to the application when the handle was created. Also, the application could be sending a kernel handle value to the driver, and the KernelMode reference on behalf of the application succeeds. Applications should never be allowed to use kernel handles

How does Driver Verifier determine whether  it  is a "blind" KernelMode access ? It cannot. The access checks are bypassed, when AccessMode is KernelMode because it is kernel mode driver that is attempting the operation and  drivers along with kernel itself, are considered part of Trusted Computing Base. Many drivers would be pointless without system-wide privileges. Furthermore, by this logic, if a driver wishes to get file owner information on a user-mode handle, but the original application handle did not have access to the owner information, driver should not do a KernelMode access to get the owner information to keep Windows 7 Driver Verifier happy. I do not know about you but that does not make much sense to me.

Granted that drivers should carefully validate all user input to prevent the case of kernel handles being passed from user-mode with malicious intent, but then again it could be a legitimate case as well. Think of an application like process explorer, that is showing kernel handles and user has just drilled down to get more information about one of the handles. Such an application may need to pass a kernel handle to its driver to get information about it. Applications cannot use kernel handles directly,  they still need a driver to access it for them.

A driver doing a privileged operation for a less privileged application is no way different from a LocalSystem service/server/daemon accessing privileged system areas on behalf of less privileged client. The service needs to be careful to validate input, sanitize output and needs to impersonate the client if  it needs to. But LocalSystem servers, by definition, need to have access beyond what the client has to be useful to the clients. Drivers being limited to UserMode access on user-mode handles, are like localsystem service forced to impersonate the client all the time, which  defeats the purpose of being a LocalSystem service in the first place.3

Windows 7 (Beta Build 7000) Driver Verifier will catch buggy drivers that unintentionally left out OBJ_KERNEL_HANDLE during handle creation. However since it cannot determine intention and checks are enforced in ObReferenceObjectByHandle,4 there will be false positives5. My beta feedback to Microsoft would be that this should instead be a checked kernel warning, not a Driver Verifier setting that is turned on as part of Standard Settings.

1appears as bit 8 (0x100) in Driver Verifier flags in Windows 7 beta build 7000

2Driver Verifier does not bugcheck the system if a Desktop or WindowStation object is being accessed in KernelMode suggesting incompatibilities with win32k.sys.

3The whitepaper goes on to state "Driver Verifier ignores KernelMode references to user handles if these references occur in the context of a process that runs under the local system account. Because these processes hold powerful privileges, they are less likely to pose a security risk." Remember Conficker worm that exploits localsystem svchost process ? By giving LocalSystem processes an exception, Driver Verifier may be staying clear of conflict with KernelMode accesses in LocalSystem processes such as win32 subsystem process csrss.exe.

4Putting Verifier checks in ObReferenceObjectByHandle is perhaps the easiest approach to catch the buggy drivers since there are so many ways to create handles in a driver. The correct check should have been to implement checks in all kernel mode handle creation routines. Even in that case it should not be a bugcheck.

5which are sometimes harder to fix when ObReferenceObjectByHandle is not called directly by a driver. If Microsoft decides to keep this as it is, the only option to stay clean for an ISV, is to spawn a worker thread that will run in LocalSystem context and therefore will get around Verifier bugcheck - which may not be the best thing to do performance-wise.

Tagged with →  
Share →

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Looking for something?

Use the form below to search the site:


Still not finding what you're looking for? Drop us a note so we can take care of it!

Visit our friends!

A few highly recommended friends...

Set your Twitter account name in your settings to use the TwitterBar Section.