Learn about two features that help eliminate device-driver errors
In Part 1 of this series about Windows 2000 (Win2K) reliability enhancements, I described new Win2K system recovery mechanisms; in Part 2, I presented measures that Win2K takes to keep a system updated with Microsoft-approved system files. This month, I describe two features
write-protected system code and the Driver Verifierthat Microsoft has added to Win2K to help identify poorly written device drivers and help developers avoid common device-driver programming errors during the development process.
Write-Protected System Code
Applications, the Win2K kernel, and device drivers all work with pointers. A pointer is a reference to a location in memory that the system allocates to a program or driver. One type of bug in programs or drivers can result in pointer corruption, in which the program or driver assigns a pointer a meaningless value instead of a valid memory address. Two other bugs that are closely related to each other are buffer overrun and buffer underrun. These bugs result when a program or driver thinks it's addressing a buffer it allocated, but in fact the pointer references memory just past the end of the buffer (overrun) or just short of the start of the buffer (underrun).
If a program or device driver with an invalid pointer writes a value to the location in memory that the pointer references, the program or driver might overwrite part of its code, part of a different buffer than the intended buffer, or unallocated memory. In the latter case, Win2K detects the error and terminates the application. If the culprit is a device driver, Win2K halts the system and displays a blue screen of death to prevent the misbehaving driver from inadvertently corrupting critical files such as the Registry or corrupting files on disk. If the memory location that the invalid pointer writes to is in a different buffer or portion of the program and the bug is in an application, Win2K will eventually detect the problem or a side effect of the problem and terminate the application. Although Win2K's memory protection prevents one application from writing to the memory of another application, in kernel mode, a device driver can write to any other device driver's memory or to the kernel's memory.
In previous versions of Windows NT, including NT 4.0 and NT 3.51, a bug in a device driver that corrupts the kernel or another driver's code or memory is difficult to identify. The system almost always eventually detects the problem when a corrupted driver or kernel performs illegal operations, but tracing the problem to its root is virtually impossible. Win2K enforces write-protected system code to help systems administrators and device-driver developers identify pointer corruption when it occurs. If a corrupt pointer references the executable code of a device driver or the kernel, the Win2K Memory Manager is aware of the overwrite operation when it occurs and therefore knows which driver is responsible for the operation. This capability limits the number of cases in which the system doesn't immediately detect corrupt pointers to cases in which the pointer references memory buffers of a different device driver or the kernel. When the system identifies a misbehaving device driver, a systems administrator can update the driver or remove it from the system.
Win2K implements system-code protection in the routine that loads the kernel image and device-driver files into memory. The function MiLoadSystemImage identifies executable code in a loading file and uses the hardware's memory management features to designate those sections of memory as write-protected. In certain situations, developers might need to disable Win2K's protection of system code areas. To do so, a developer sets the HKEY_LOCAL_MACHINE\ SYSTEM\CurrentControlSet\ Control\Memory ManagerEnforceWriteProtection Registry value to 0.
The Driver Verifier
A new feature in Win2K, the Driver Verifier (or Verifier), is probably the most powerful tool in Win2K's reliability arsenal. Much as write-protected system memory does, the Verifier consists of code in the Win2K kernel that, when applied to a device driver, detects common device-driver bugs as they occur. For example, although write-protected system memory lets Win2K catch memory modifications in device drivers or kernel code that corrupt pointers reference, the Verifier detects many types of modifications that corrupt pointers make that reference data buffers. If a device driver with a bad pointer causes a buffer overrun that corrupts another driver's memory in NT 4.0, the error might go undetected indefinitely, which makes isolating the buggy device driver impossible. But with the Verifier, Win2K usually can detect such a bug immediately. The Verifier also detects other common device-driver programming mistakes.
You use the Verifier GUI (\%systemroot%\system32\verifier.exe) to configure the Verifier and view statistics about operations that the Verifier code executing in the kernel makes. The Verifier GUI property sheet includes several tabbed pages. You use the Modify Settings tab to specify which device drivers you want to verify and what types of verification the kernel performs. Registry settings that the Verifier modifies when you select options on the Modify Settings tab reside under HKEY_LOCAL_
MACHINE\SYSTEM\CurrentControlSet\ Control\Memory Management and include the REG_DWORD value VerifyDriverLevel and the string value VerifyDrivers. The Win2K kernel interprets VerifyDriverLevel as a bit mask, and each position in the mask represents one of the verification types listed on the right side of the Modify Settings page. When you select specific drivers to validate, the Verifier stores their names in VerifyDrivers. An exception occurs when you tell the Verifier to verify all drivers; the Verifier will then set VerifyDrivers to the asterisk (*) wildcard character.
After you've entered or changed Verifier settings, you must reboot the system. Early in the boot process, the Win2K Memory Manager reads the Verifier Registry values to determine which drivers to verify and which Verifier options you enabled. Subsequently, if you've selected at least one driver for verification, the kernel checks the name of every device driver it loads into memory against the list of drivers that you've selected for verification. For every device driver that appears in both places, the kernel invokes the MiApplyDriverVerifier function, which replaces the driver's references to any of approximately 40 kernel and Win32K.sys (the kernel-mode Win32 subsystem) functions with references to Verifier-equivalent versions of those functions.
The kernel functions to which MiApplyDriverVerifier redirects device drivers are associated with the kinds of checks that the Verifier performs. For example, the Verifier intercepts all of a verified device driver's buffer allocation and deallocation functions. If a device driver under verification usually uses the kernel function ExAllocatePool to allocate memory, the driver uses VerifierAllocatePool instead.
Prev. page  
[1]
2
next page