Description
If code validates a value in user-controlled memory and then reads that location again for use, the value can change between the check and the operation.
Potential impact
- Validation bypass, buffer overflow or information disclosure across a kernel or native-code boundary.
Remediation
Copy each field used for validation into a trusted local variable once, then validate and use that same local value. If several fields must agree, safely capture the complete request and validate their relationships too.
Examples
Before
ProbeForRead(req, sizeof(*req), 1);
if (req->len > MAX) { return; }
RtlCopyMemory(dst, req->buf, req->len);
After
ProbeForRead(req, sizeof(*req), 1);
size_t len = req->len;
if (len > MAX) { return; }
RtlCopyMemory(dst, req->buf, len);
The first excerpt reads the checked field again when copying. The second validates and uses the same local copy of the length.
This excerpt removes only the second length read. MAX must not exceed the destination capacity, and req->buf and the actual memory access require separate validation. In a Windows driver, wrap ProbeForRead and subsequent user-memory accesses in exception handling. ProbeForRead does not pin the memory or prevent other threads from changing it.