# CVE-2025-62464 — Windows Projected File System `prjflt.sys` Validate/Advance Mismatch on `NextEntryOffset == 0` → Buffer Over-Read

---

## Summary

| | |
|---|---|
| **Product** | Windows — `prjflt.sys` (Windows Projected File System / ProjFS minifilter; enumeration merge) |
| **CVE ID** | CVE-2025-62464 |
| **Impact** | Elevation of Privilege (kernel pool information disclosure) |
| **MSRC severity** | Important |
| **CVSS** | 7.8 / 6.8 — `CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H/E:U/RL:O/RC:C` |
| **CWE** | CWE-126: Buffer Over-read |
| **Delivery** | Local — a crafted multi-entry ProjFS directory-enumeration result |
| **KB / Fixed build** | KB5072033 — `prjflt.sys` 10.0.26100.7462 (Win11 24H2 x64) |
| **Patch Date** | December 9, 2025 (2025-Dec) |
| **Pre-patch binary** | `prjflt.sys` 10.0.26100.7309 — SHA256 `933e0862552cf839905efb55bd867a43881eed1680051096d6b6b5250e5674c8` |
| **Post-patch binary** | `prjflt.sys` 10.0.26100.7462 — SHA256 `2a9350bc757df5a7480494b2faf40813731baf0dd26c6383b6d86f46dee68468` |
| **Feature flag** | `Feature_3797454136` — **the fix is CFR-gated** |
| **Exploitability** | Exploitation Less Likely; not publicly disclosed; not exploited (per MSRC) |

---

## Product Description

When ProjFS merges a directory-enumeration result into the caller's buffer, it
validates each entry with `PrjfValidateNamesInEnumeration` and walks entries with
`PrjfAdvanceToNextEnumEntry` (driven from `PrjfMergeEnumerationResults`). Each
directory-info entry carries a `NextEntryOffset` linking to the next entry; a
`NextEntryOffset` of `0` conventionally marks the **last** entry.

---

## Vulnerability Summary

The validator and the advancer disagreed on what `NextEntryOffset == 0` means.
`PrjfValidateNamesInEnumeration`, on reaching an entry whose `NextEntryOffset` is
`0`, validates that entry and **returns** (treating it as the last):

```c
// PrjfValidateNamesInEnumeration (pre) — from the reporter analysis
NextEntryOffset = DirEntry->NextEntryOffset;
if (!NextEntryOffset) return Status;   // stop after this entry
```

`PrjfAdvanceToNextEnumEntry`, however, still **advanced** past a zero
`NextEntryOffset` by computing `FileNameOffset + FileNameLength`:

```c
// PrjfAdvanceToNextEnumEntry (pre) — from the reporter analysis
if (!NextEntryOffset) EntryOffset = FileNameOffset + FileNameLength; // advance anyway
Context->EntryOffset += EntryOffset;
```

So for a result buffer holding two entries where the first entry's
`NextEntryOffset` is `0`, only the **first** entry is validated, yet the merge
advances to the **second, unvalidated** entry and
`PrjfMungeDirectoryEnumerateWithoutShortname` copies its attacker-shaped
`FileName` — including adjacent kernel pool — into the caller's buffer (CWE-126).
Because ProjFS runs in the kernel and the enumeration is reachable locally, the
disclosed pool is a local EoP primitive.

---

## Prerequisites and Constraints

- Local, low-privileged (`PR:L`, `AV:L`, `AC:L`): drive a ProjFS enumeration whose
  result buffer the attacker shapes.
- Place two entries in the buffer; set the first entry's `NextEntryOffset = 0` and
  craft the second entry to over-read.
- Result: the second entry is copied to the user buffer without validation.

---

## Vulnerability Details

### Root Cause

`PrjfValidateNamesInEnumeration` stopped at `NextEntryOffset == 0` while
`PrjfAdvanceToNextEnumEntry` still advanced past it, so an entry could be copied
that was never validated.

### The patch (confirmed — diff, .7309 → .7462)

Gated behind `Feature_3797454136`, `PrjfAdvanceToNextEnumEntry` **no longer
advances past a zero `NextEntryOffset`** — it sets the running entry offset to
`0xffffffff` (an invalid/stop marker) instead of adding
`FileNameOffset + FileNameLength`, bringing advancement into agreement with the
validator:

```c
// PrjfAdvanceToNextEnumEntry (10.0.26100.7462) — PATCHED, feature-enabled branch (from our diff)
if (Feature_3797454136__private_IsEnabledDeviceUsageNoInline() && NextEntryOffset == 0) {
    *(undefined4 *)(param_1 + 0x30) = 0xffffffff;   // stop; do not advance
}
// else (feature) advance by the checked delta
```

With advancement halting at `NextEntryOffset == 0`, the merge can no longer reach
an unvalidated entry, closing the over-read.

### Patch Completeness Assessment

**CFR-gated behind `Feature_3797454136`.** The stop-on-zero behaviour runs only
when the flag is enabled; the original advancing path still ships when disabled.
Verify `Feature_3797454136` is enabled to confirm the fix is live.

---

## Detection Guidance

**Behavioural.** ProjFS enumeration result buffers with a mid-buffer
`NextEntryOffset == 0` followed by further entry data; over-read / pool-read
anomalies from `prjflt!PrjfAdvanceToNextEnumEntry` /
`PrjfMungeDirectoryEnumerateWithoutShortname` on unpatched/flag-disabled builds.

**Config.** The fix is CFR-gated — confirm `Feature_3797454136` is enabled.

---

## References

- MSRC advisory — CVE-2025-62464 (Windows Projected File System Elevation of Privilege), released 2025-12-09, KB5072033.
- Full binary diff: `/data/patch_diffs/prjflt_sys-kb5072033-dec2025-ghidriff.md`
- Related same-KB ProjFS enumeration info-leaks: CVE-2025-62462, CVE-2025-62467, CVE-2025-55233.
