Making sure the IO manager evaluates the security of your device

Last time I wrote about how the IO manager handles the creation of file handles and pointed out a potential security hole.  If there is a namespace (or path) after your device's name in the path passed to CreateFile, the IO managed does not evaluate the security settings set on your device and relies on your driver to do the evaluation.   For instance, if you create a device object and specify that only administrators have access to it and you do not validate access during IRP_MJ_CREATE processing, any user regardless of privilege level may open a handle to your device if they specify any namespace (i.e. "\Device\FooDevice\Blah") when opening a handle. 

A gut shot reaction to this behavior is that is a very large tax for every device driver to pay and the NT kernel developers agreed.  To rectify the situation a new characteristics flag, FILE_DEVICE_SECURE_OPEN, was added.  This flag tells the IO manager that when a device namespace is present during handle creation that the IO manager should no longer skip the security check and should still evaluate if the caller has sufficient rights to open the device.  By setting this flag, the caller's access to the object is always evaluated at the IO manager level and the driver does nothing more then set this flag. 

You might say to yourself, "well that is backwards, shouldn't the driver writer get this behavior by default and choose to opt out of it instead of knowing that the device must opt in to get the most secure behavior?" and I would agree with you.  The reason the most secure behavior was not made default was for backwards compatibility.  This hole was not discovered until after NT 3.1 shipped and if the IO manager behavior was flipped, already shipping drivers would stop functioning.

So when should you set this flag?  In my opinion you should always set this flag in a WDM driver!  The one exception is if you are creating a device upon which a file system will be mounted (if you set the flag in this case, the file system will not be able to evaluate the security of the namespace string).  In the opinion of the WDF team, this flag is so important that we tried to guarantee that this flag is set for all WDF device objects, even if you tried to clear it by calling WdfDeviceInitSetCharacteristics or WdfDeviceSetCharacteristics.  If you are writing a KMDF driver which will have a file system mounted on top of it, this is how you would clear the flag after creating the WDFDEVICE

 WdfDeviceWdmGetDeviceObject(device)->Characteristics &= ~FILE_DEVICE_SECURE_OPEN;

This KB article also discusses the side effects of the FILE_DEVICE_SECURE_OPEN flag on inbox drivers in previous OS releases.