# CVE-2025-55233 — Windows Projected File System `prjflt.sys` Relative-Path Length Underflow in `PrjfExpandFile` → Out-of-Bounds Read

---

## Summary

| | |
|---|---|
| **Product** | Windows — `prjflt.sys` (Windows Projected File System / ProjFS minifilter; file expansion) |
| **CVE ID** | CVE-2025-55233 |
| **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-125: Out-of-bounds Read |
| **Delivery** | Local — a ProjFS expansion/notification for a file whose path equals the virtualization root |
| **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_3579016506` — **the fix is CFR-gated** |
| **Exploitability** | Exploitation Less Likely; not publicly disclosed; not exploited (per MSRC) |

---

## Product Description

`PrjfExpandFile` runs when ProjFS needs to notify/expand a virtualized file. It
derives the file's path **relative to the virtualization root** and sends it to the
user-mode provider in a command buffer:

```c
// PrjfExpandFile — from the reporter analysis
Status = FltGetFileNameInformationUnsafe(FileObject, Instance, 0x101, &FileNameInfo);
RootLength      = UnionContext->usVirtRoot.Length;
usRel.Buffer    = FileNameInfo->Name.Buffer + RootLength + 2;
usRel.Length    = FileNameInfo->Name.Length - RootLength - 2;   // <-- relative length
usRel.MaximumLength = usRel.Length;
PrjfSendNotifyOperationCommand(..., &usRel, ...);
```

The `FileNameInfo` allocation is `0x160` bytes; `usRel` (offset into
`FileNameInfo->Name.Buffer`) is copied into the command's `RelPathBuffer` and
delivered to the client port via `FltSendMessage`.

---

## Vulnerability Summary

`usRel.Length` is computed as `FileNameInfo->Name.Length - RootLength - 2` without
first checking that the file name is actually **longer** than the root. When the
`FileObject`'s path **equals the virtualization root**, `Name.Length ==
RootLength (+ separator)`, so the subtraction **underflows** to `0xFFFE` (a
`USHORT`):

```c
usRel.Length = Name.Length - RootLength - 2;   // 0 - 2 => 0xFFFE
```

`~0xFFFE` bytes of `usRel.Buffer` are then copied into
`CommandBuffer->RelPathBuffer` and sent to the user-mode port. Because the source
`FileNameInfo` block is only `0x160` bytes, the copy reads far past it into
adjacent kernel pool, and that pool is disclosed to user mode inside the command
message (CWE-125). ProjFS runs in the kernel and expansion is reachable locally, so
this is a local EoP/information-disclosure primitive.

Reaching `PrjfExpandFile` with the root as the target requires driving expansion
via `PrjfExpandAndWait` / `PrjfExpandAndPend`, subject to the `StreamContext->FileType`
gate the reporter documents.

---

## Prerequisites and Constraints

- Local, low-privileged (`PR:L`, `AV:L`, `AC:L`): trigger a ProjFS
  expansion/notification whose `FileObject` path is the virtualization root itself.
- The subtraction `Name.Length - RootLength - 2` underflows to `0xFFFE`.
- Result: the relative-path copy over-reads adjacent pool, delivered to the client
  port via `FltSendMessage`.

---

## Vulnerability Details

### Root Cause

The relative-path length was computed by subtracting the root length from the name
length without validating that the name is strictly longer than the root, so a
name equal to the root underflowed the `USHORT` length to `0xFFFE`.

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

Gated behind `Feature_3579016506`, `PrjfExpandFile` **validates the name-vs-root
length relationship before deriving `usRel`**, rejecting the entry
(`STATUS_OBJECT_NAME_INVALID`, `0xC0000033`) when the name is not properly longer
than the root, so the length can no longer underflow:

```c
// PrjfExpandFile (10.0.26100.7462) — PATCHED, feature-enabled branch (from our diff)
uVar8 = Feature_3579016506__private_IsEnabledDeviceUsageNoInline();
if (((int)uVar8 == 0) || (Name.Length < RootRelatedLength)) {   // name must exceed root
    ... proceed ...
} else {
    Status = 0xC0000033;   // reject: would underflow
}
```

With the relationship enforced, a `FileObject` whose path equals the virtualization
root is rejected rather than producing a `0xFFFE`-length relative path, closing the
out-of-bounds read.

### Patch Completeness Assessment

**CFR-gated behind `Feature_3579016506`.** The length validation runs only when the
flag is enabled; the original underflowing path still ships when disabled. Verify
`Feature_3579016506` is enabled to confirm the fix is live.

---

## Detection Guidance

**Behavioural.** ProjFS notify/expand commands carrying an unusually long
(`~0xFFFE`) relative path; large `RelPathBuffer` payloads to the client port from
`prjflt!PrjfExpandFile` → `FltSendMessage`; pool-read anomalies on
unpatched/flag-disabled builds.

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

---

## References

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