Common Driver Reliability Issues
June 2004Applies to: Microsoft Windows 98 / Windows Me Microsoft Windows 2000 Microsoft Windows XP Microsoft Windows Server 2003 Microsoft Windows codenamed «Longhorn»Summary: This paper provides information about writing drivers for the Microsoft Windows family of operating systems. (37 printed pages)Drivers occupy a significant portion of the total code base executed in kernel mode. Consequently, efforts to improve the reliability and security of the system must address this large code base.This paper describes a variety of problems commonly seen in drivers, often with code that shows typical errors, and how to fix them. The code has been edited for brevity.This paper is for developers who are writing kernel mode drivers. The information in this paper applies for the Microsoft Windows family of operating systems.User Mode Addresses in Kernel Mode CodeWhen providing services to user mode code, drivers and other kernel mode components usually receive and return data in buffers. To avoid corruption of data, disclosure of sensitive or security critical data, or exceptions that cannot be handled by the try/except mechanism, kernel components must ensure that each data pointer they receive from user mode is a valid user mode pointer. This operation is called probing.Drivers must obey the following rules when handing pointers obtained from user mode:Probe all user mode pointers before referencing them.To probe a pointer, use the macro ProbeForRead or ProbeForWrite, or the memory management routine MmProbeAndLockPages.Enclose all references to user mode pointers in try/except blocks. The mapping of user mode memory can change at any instant for various reasons, such as address space deletion, protection change, or decommit. Therefore, any reference to a user mode pointer could raise an exception.Assume that user mode pointers can be aligned on any boundary.Be prepared for changes to the contents of user mode memory at any time; another user mode thread in the same process might change it. Drivers must not use user mode buffers as temporary storage, or expect the results of double fetches to yield the same results the second time.Validate all data received from user mode code.Handling user mode pointers incorrectly can result in the following:Crashes caused by references to portions of the kernel address space that the Memory Manager considers reserved. It is a serious error for any driver to reference such address space.Crashes caused by references to input/output (I/O) space, if the architecture uses memory mapped device registers. Such references (reads and writes) can also have negative effects on the device itself.Disclosure of sensitive data if the caller passes a pointer to an area that is unreadable by user mode, then observes the driver responses or return values to deduce the contents of the protected location. These samples represent fictitious system service routines, but could also be driver routines keyed on input/output control (IOCTL) or file system control (FSCTL) values; the only difference is that the driver code is more complicated. These routines show a situation in which probing is necessary. To simplify the example, the sample routines do not include locks to prevent race conditions and similar details that normally should be present in such code.SetUserData receives a buffer from user mode and copies it to a global location. This routine represents any kernel component that receives data from user mode.