# cldflt.sys Patch Diff — CVE-2025-55680

| | |
|---|---|
| Binary | cldflt.sys (Cloud Files Minifilter Driver) |
| Pre-patch version | 10.0.26100.6725 (Windows 11 24H2, KB5065789, September 2025 preview) |
| Post-patch version | 10.0.26100.6899 (Windows 11 24H2, KB5066835, October 2025) |
| KB | KB5066835 |
| CVE | CVE-2025-55680 — Cloud Files Mini Filter TOCTOU Elevation of Privilege (arbitrary file/dir creation), CVSS 7.x |
| Diff tool | ghidriff (Ghidra VersionTrackingDiff, Ghidra 12.1.2, full cldflt.pdb symbols), cross-checked live via GhidraMCP |
| Vulnerable function | `cldflt!HsmpOpCreatePlaceholders` |
| Fix pattern | Snapshot the user payload into a kernel pool buffer (`memcpy`) before validate + use, behind new WIL flag `Feature_4257790267` |

> **Status: VERIFIED (2026-07-20).** ghidriff diff completed (2,848/2,852
> functions matched, 4 code-changed, 4 added) **and** both builds decompiled
> live via GhidraMCP: pre-patch `HsmpOpCreatePlaceholders` @ `0x14005e934`
> contains the double-fetch; post-patch @ `0x14005e954` contains the
> pool-copy fix behind `Feature_4257790267`.

## Summary

`HsmpOpCreatePlaceholders()` handles `CfCreatePlaceholders()` requests
(IOCTL `0x903BC`, Tag `0x9000001A` = `IO_REPARSE_TAG_CLOUD`, OpType
`0xC0000001`). In the pre-patch build, the caller's placeholder payload is a
**userspace buffer** mapped into kernel VA with `IoAllocateMdl` +
`MmProbeAndLockPages` + `MmMapLockedPagesSpecifyCache`, so the kernel mapping
and the user buffer share the same physical pages:

```c
// PRE-PATCH .6725 — verified @ 0x14005e934
mdl = IoAllocateMdl(placeholderPayload, placeholderPayload_size, 0, 0);
ProbeForRead(param_4, param_5, 4);
MmProbeAndLockPages(mdl, 1, Feature_2594491707-enabled);
mapped = MmMapLockedPagesSpecifyCache(mdl, 0, MmCached, 0);
```

For each placeholder it then performs the double-fetch:

1. **[CHECK]** scans `relName` **in the mapped (user-shared) buffer** and
   bails with `0xC000CF0B` if any wide char is `\` (0x5C) or `:` (0x3A);
2. **[USE]** builds `ObjectAttributes` with `ObjectName` pointing at the
   **same mapped buffer's** `relName` (`puStack_130 = *pauVar1 +
   relName_offset`) and calls `FltCreateFileEx2()`.

Between [CHECK] and [USE] a second userspace thread flips one character of
`relName` from `D` to `\` (e.g. `JUSTASTRINGDnewfile.dll` →
`JUSTASTRING\newfile.dll`). If `JUSTASTRING` is a junction to a directory the
user cannot write (e.g. `C:\Windows\System32`), the create follows the
junction and the file lands in the protected directory → arbitrary
file/directory creation as SYSTEM → DLL side-load privesc.

## The patch (verified)

The post-patch build adds a new WIL Controlled-Feature-Rollout flag,
`Feature_4257790267`, and behind it **replaces the MDL mapping with a
private pool snapshot** of the entire payload:

```c
// POST-PATCH .6899 — verified @ 0x14005e954
uVar7 = Feature_4257790267__private_IsEnabledDeviceUsageNoInline();
if (uVar7 == 0) {
    // legacy path: IoAllocateMdl + ProbeForRead + MmProbeAndLockPages
    //              + MmMapLockedPagesSpecifyCache  → shared pages (vulnerable)
} else {
    local_178 = ExAllocatePool2(0x102 /*NonPagedPoolNx*/, param_5, 'HsSp');
    ProbeForWrite(param_4, param_5, 4);
    memcpy(local_178, param_4, param_5);      // ← snapshot payload into private pool
}
```

Every subsequent read in the entry loop — the `\`/`:` scan **and** the
`ObjectName.Buffer` handed to `FltCreateFileEx2` — now dereferences the
private pool copy (`pauVar9 = local_178 + offset`), so mutating the
userspace buffer mid-flight has no effect. On the success path the results
are copied back (`memcpy(param_4, local_178, param_5)`) before the pool is
freed, preserving the API contract.

Note the CFR pattern, same as CVE-2026-42980: the safe code ships compiled
in the binary, gated by a WIL flag. Unlike that ntoskrnl case, here the
**branch itself is new code**, so a function-level diff does show
`HsmpOpCreatePlaceholders` as changed (+0x20 entry-point shift and a larger
function body).

## Functions changed (verified)

| Function | Pre-patch | Post-patch | Change |
|---|---|---|---|
| `cldflt!HsmpOpCreatePlaceholders` | `0x14005e934` | `0x14005e954` | **code** — new `Feature_4257790267` branch: pool snapshot (`ExAllocatePool2` + `ProbeForWrite` + `memcpy`) replaces MDL shared mapping; result copy-back + pool free on exit |
| `Feature_4257790267__private_IsEnabledDeviceUsageNoInline` (+ fallback/reporting) | — | present | **added** — CFR kill-switch plumbing for the new path |
| `Feature_2594491707__private_IsEnabledDeviceUsageNoInline` | present | present | unchanged (pre-existing flag toggling `MmProbeAndLockPages` access mode; not the fix) |

### Call chain (userspace → bug)

```
CfCreatePlaceholders()                    (cldapi.dll)
  └─ NtFsControlFile(BaseDir, 0x903BC)    input: ioctl_0x903BC { Tag=0x9000001A, OpType=0xC0000001, size>=0x50, payload* }
       └─ cldflt!HsmFltPreFILE_SYSTEM_CONTROL
            └─ HsmiOpPrepareOperation
                 └─ HsmFltProcessCreatePlaceholders   [size checks: nInBufferSize >= 0x20, payload >= 0x50]
                      └─ HsmpRelativeStreamOpen(BaseDirectoryPath)
                      └─ HsmpOpCreatePlaceholders     ← TOCTOU window: relName check → FltCreateFileEx2
```

## Userspace reach (hint)

- `CfRegisterSyncRoot()` — register any directory you own as a sync root
  (cldapi.dll; no admin needed).
- Create directory `JUSTASTRING` inside the sync root; turn it into a
  **junction** to a target (e.g. `C:\Windows\System32`).
- `CfCreatePlaceholders(BaseDirectoryPath = <dir in sync root>, …)` with
  `RelativeFileName = L"JUSTASTRINGDnewfile.dll"` (or issue IOCTL `0x903BC`
  directly via `NtFsControlFile` for full control of the buffer).
- Race threads flip the flip-target char (`D` ↔ `\`) while a monitor thread
  watches for the file to appear in the junction target.

See `poc/poc_cve_2025_55680.c` for the full trigger skeleton.

---

<sub>Source: ghidriff diff of cldflt-10.0.26100.6725.sys (KB5065789,
pre-patch) vs cldflt-10.0.26100.6899.sys (KB5066835, post-patch), Windows 11
24H2; raw report in `ghidriff/CVE-2025-55680/ghidriffs/`. Fix verified by
live GhidraMCP decompilation of both builds (`HsmpOpCreatePlaceholders`:
0x14005e934 pre / 0x14005e954 post; new flag
`Feature_4257790267`). Mechanism and IOCTL layout per the Exodus
Intelligence analysis ([writeup](https://blog.exodusintel.com/2025/10/20/microsoft-windows-cloud-files-minifilter-toctou-privilege-escalation/)).</sub>
