The following sections consider where data corruption can occur and the steps you can take to detect it.
The driver should assume that any data obtained from the device, whether by PIO or DMA, could have been corrupted. In particular, extreme care should be taken with pointers, memory offsets, or array indexes read or calculated from data that is supplied by the device. Such values can be malignant, meaning they can cause a kernel panic if dereferenced. All such values should be checked for range and alignment (if required) before use.
Even if a pointer is not malignant, it can still mislead. For example, it can point at a valid instance of an object, but not the correct one. Where possible, the driver should cross-check the pointer with the pointed-to object, or otherwise validate the data obtained through it.
Other types of data can also be misleading, such as packet lengths, status words, or channel IDs. Each type of data should be checked to the extent possible: a packet length can be range-checked to ensure that it is not negative or larger than the containing buffer; a status word can be checked for ”impossible” bits; and a channel ID can be matched against a list of valid IDs.
Where a value is used to identify a Stream, the driver must ensure that the Stream still exists. The asynchronous nature of STREAMS processing means that a Stream can be dismantled while device interrupts are still outstanding.
The driver should not reread data from the device. The data should be read once, validated, and stored in the driver's local state. This avoids the hazard presented by data that, although correct when initially read and validated, is incorrect when reread later.
The driver should also ensure that all loops are bounded so that a device returning a continuous BUSY status, or claiming that another buffer needs to be processed, does not lock up the entire system.
Device errors can result in corrupted data being placed in receive buffers. Such corruption is indistinguishable from corruption that occurs beyond the domain of the device—for example, within a network. Typically, existing software is already in place to handle such corruption; for example, through integrity checks at the transport layer of a protocol stack or within the application using the device.
If the received data will not be checked for integrity at a higher layer—as in the case of a disk driver, for example—it can be integrity-checked within the driver itself. Methods of detecting corruption in received data are typically device-specific (checksums, CRC, and so forth).
Any ancestor of a device driver can disable the data path to the device if it detects a fault. When PIO access is disabled, any reads from the device return undefined values, while writes are ignored. If DMA access is disabled, the device might be prevented from accessing memory, or it might receive undefined data on reads and have writes discarded.
A device driver can detect that a data path has been disabled by using the following DDI routines:
Each function checks whether any faults affecting the data path represented by the supplied handle have been detected. If one of these functions returns DDI_FAILURE, indicating that the data path has failed, the driver should report the fault by using ddi_dev_report_fault(9F), perform any necessary cleanup, and, where possible, return an appropriate error to its caller.