# CVE-2025-62467 — Windows Projected File System `prjflt.sys` `FileNameLength` ULONG→USHORT Truncation in `PrjfValidateNamesInEnumeration` → Buffer Over-Read

---

## Summary

| | |
|---|---|
| **Product** | Windows — `prjflt.sys` (Windows Projected File System / ProjFS minifilter; enumeration validation) |
| **CVE ID** | CVE-2025-62467 |
| **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-190: Integer Overflow/Wraparound (truncation) + CWE-126: Buffer Over-read |
| **Delivery** | Local — a crafted ProjFS directory-enumeration result entry |
| **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_4287139131` — **the fix is CFR-gated** |
| **Exploitability** | Exploitation Less Likely; not publicly disclosed; not exploited (per MSRC) |

---

## Product Description

`PrjfValidateNamesInEnumeration` validates each directory-information entry in a
ProjFS enumeration result before it is merged into the caller's buffer. For a
`FILE_ID_EXTD_DIR_INFORMATION` entry the important fields are `NextEntryOffset`,
`FileNameLength` (a **`ULONG`**), and the inline `FileName`:

```c
typedef struct _FILE_ID_EXTD_DIR_INFORMATION {
    ULONG NextEntryOffset; ULONG FileIndex; /* ... */
    ULONG FileNameLength;                 // entry + 0x3C, ULONG
    ULONG EaSize; ULONG ReparsePointTag; FILE_ID_128 FileId;
    WCHAR FileName[];                     // entry + 0x58
} FILE_ID_EXTD_DIR_INFORMATION;
```

---

## Vulnerability Summary

Pre-patch, `PrjfValidateNamesInEnumeration` read `FileNameLength` **as a `USHORT`**
before bounding and scanning the name:

```asm
movzx   r8d, word ptr [rbx+3Ch]     ; FileNameLength truncated to 16 bits
```

```c
// pre-patch validation (from the reporter analysis)
FileNameLength = (USHORT)entry->FileNameLength;   // truncated
Length = FileNameLength >> 1;
if (Length > 0x104) return STATUS_OBJECT_NAME_INVALID;
// scan only 'Length' chars of FileName ...
```

Because only the low 16 bits are validated, a `FileNameLength` of `0x10000C` is
checked as `0xC`, so only the first `0xC` bytes of `FileName` are validated. The
downstream copier, however, uses the **full `ULONG`**:

```c
// PrjfMungeDirectoryEnumerateWithoutShortname (and similar)
memmove(OutEntryBuffer->DirInfo.FileName, Entry->FileName, FileNameLength); // 0x10000C
```

So the validated `0xC` bytes plus an unchecked `0x10000` bytes of adjacent kernel
pool are copied into the user buffer — a truncation (CWE-190) that bypasses
validation and produces a pool over-read (CWE-126) disclosed to the caller.

---

## Prerequisites and Constraints

- Local, low-privileged (`PR:L`, `AV:L`, `AC:L`): drive a ProjFS enumeration whose
  result entry the attacker shapes (via the provider/complete-command path).
- Set a directory entry's `FileNameLength` so its low 16 bits pass validation while
  the full `ULONG` is large (e.g. `0x10000C`).
- Result: the copier moves the full `ULONG` length, leaking unvalidated pool bytes.

---

## Vulnerability Details

### Root Cause

Validation truncated the `ULONG` `FileNameLength` to a `USHORT`, so the bound it
enforced did not match the full-width length used by the copy path.

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

Gated behind `Feature_4287139131`, `PrjfValidateNamesInEnumeration` now **rejects
any entry whose full `ULONG` `FileNameLength` exceeds `0xffff`** before the USHORT
truncation, for each directory-information class:

```c
// PrjfValidateNamesInEnumeration (10.0.26100.7462) — PATCHED, feature-enabled branch (from our diff)
if (Feature_4287139131__private_IsEnabledDeviceUsageNoInline() && (0xffff < param_2[2]))
    return 0xC000000D;                 // STATUS_INVALID_PARAMETER (full ULONG length)
uVar8 = (ushort)param_2[2];            // only then narrow for the scan
```

(The same full-width `> 0xffff` check is added for the other directory-info classes,
e.g. `param_2[0xf]`.) With the full `ULONG` validated, an over-length name can no
longer pass validation while being copied in full, closing the over-read.

### Patch Completeness Assessment

**CFR-gated behind `Feature_4287139131`.** The full-width check runs only when the
flag is enabled; the original truncating check still ships when disabled. Verify
`Feature_4287139131` is enabled to confirm the fix is live.

---

## Detection Guidance

**Behavioural.** ProjFS enumeration entries whose `FileNameLength` high bits are
non-zero (full `ULONG` > `0xffff`); over-read / pool-read anomalies from
`prjflt!PrjfValidateNamesInEnumeration` / `PrjfMungeDirectoryEnumerateWithoutShortname`
on unpatched/flag-disabled builds.

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

---

## References

- MSRC advisory — CVE-2025-62467 (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-62464, CVE-2025-55233.
