Beware using user mode handles in a driver

Driver Verifier has been updated in Win7 and several new checks have been added. One of the more interesting checks is the check for accessing user mode handles for kernel mode access. So, for example, take a handle from a user mode application and call ObReferenceObjectByHandle specifying KernelMode as the access mode. Prior to Windows 7 this would bypass any access checking and provide the underlying object pointer. On Windows 7 it will do the same without Verifier enabled, but with Verifier enabled you’ll receive a DRIVER_VERIFIER_DETECTED_VIOLATION (0xC4)/0xF6 bugcheck.

The reasons behind this check are, of course, security and reliability. The problem with user handles is that the user mode application has access to them as well as the driver. So, for example, the application could close the handle or the object that the handle maps to could change by the application opening and closing things while the driver is working with the handle.

Fixing this crash is quite simple in a driver by:

1) Always specifying OBJ_KERNEL_HANDLE in your OBJECT_ATTRIBUTES structures when creating a new handle. An alternative to this is to make sure that you always open your files in the context of the System process.

2) If you’re working with a user mode handle, always specify UserMode as the access mode parameter to any API that requires one.

One final thing that I’ll mention is that kernel handles have an interesting characteristic on Windows 2000 and Windows XP: IRP_MJ_CREATE and IRP_MJ_CLEANUP operations for kernel handles are sent in the context of the System process. Thus, if you specify OBJ_KERNEL_HANDLE and call ZwCreateFile, the I/O manager will call KeStackAttachProcess and force a switch into the System process before calling the target driver with an IRP_MJ_CREATE. Once the target driver completes the IRP, the I/O manager will switch back into the original process context. Later when you ZwClose the handle, the I/O manager will again switch back into the System process before sending the IRP_MJ_CLEANUP to the target driver. Any other operation against the handle arrives in the context of the requesting process, which can lead to some strange behavior if the target driver pays attention to such things.

Leave a Reply