CVE-2026-20820 Root Cause Analysis
Inbits Blog provides a root cause analysis of CVE-2026-20820, a Windows CLFS.sys driver vulnerability patched in January 2026. The CclfsRequest::ScanContainers function calculates the expected output length as ContainerCount * 0x240 (size of CLS_CONTAINER_INFORMATION) but fails to account for the 0x38-byte CLS_SCAN_CONTEXT object that also occupies the output buffer. This causes up to 0x38 bytes of the last CLS_CONTAINER_INFORMATION object (State, PhysicalContainerId, LogicalContainerId, and final 0x28 bytes of FileName) to be written past the buffer boundary. The analysis includes patch diffing showing the added bounds check and integer overflow guard, and confirms the bug via a guard-page BSOD proof of concept. The author notes the MSRC advisory classifies it as heap-based overflow but the observed behavior is an overflow of System PTE pages mapped for the MDL output buffer. CravateRouge independently confirms the same root cause, IOCTL mechanism, and MDL-backed buffer behavior.
Research notes
- Root causeThe CclfsRequest::ScanContainers function calculates expected output length as ContainerCount * 0x240 but fails to account for the 0x38-byte CLS_SCAN_CONTEXT object that precedes the container data in the output buffer, causing up to 0x38 bytes of out-of-bounds write.
- Technical detailThe IOCTL 0x80076816 uses METHOD_OUT_DIRECT: the output buffer is Direct I/O (MDL-backed) and serves as both input (CLS_SCAN_CONTEXT) and output (CLS_CONTAINER_INFORMATION array). The overflow writes the State, PhysicalContainerId, LogicalContainerId, and final 0x28 bytes of FileName past the buffer boundary.
- PoC researchA guard-page BSOD proof of concept confirms the vulnerability: positioning the user-land buffer at the end of a memory page with an adjacent guard page causes a kernel page fault when the driver writes beyond the buffer.
- ContextThe author notes the MSRC advisory classifies the CVE as a heap-based buffer overflow, but the observed overflow occurs in System PTE pages mapped for the MDL output buffer, not a heap allocation. The discrepancy is unresolved.