# CVE-2026-26184 — Windows Projected File System `prjflt.sys` Under-Validated `VolumeLength` in `PrjfPortConnect` → Buffer Over-Read

---

## Summary

| | |
|---|---|
| **Product** | Windows — `prjflt.sys` (Windows Projected File System / ProjFS minifilter; port connect) |
| **CVE ID** | CVE-2026-26184 |
| **Impact** | Elevation of Privilege |
| **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 (WCHAR length treated as byte length) |
| **Delivery** | Local — a crafted `FltConnectCommunicationPort` connection context to the ProjFS port |
| **KB / Fixed build** | KB5083769 — `prjflt.sys` 10.0.26100.8246 (Win11 24H2 x64) |
| **Patch Date** | April 14, 2026 (2026-Apr) |
| **Pre-patch binary** | `prjflt.sys` 10.0.26100.8115 — SHA256 `51d12b128e33bc0110344cea5c6374192d525c9f918666c9886a57c5486e5d3d` |
| **Post-patch binary** | `prjflt.sys` 10.0.26100.8246 — SHA256 `6eeb5961eb44704a1515a3df15bbf02ce4e63c55b46fb00158a5d65c7b4fd555` |
| **Feature flag** | `Feature_3411221816` — **the fix is CFR-gated** |
| **Exploitability** | Exploitation Less Likely; not publicly disclosed; not exploited (per MSRC) |

---

## Product Description

`PrjfPortConnect` is the ProjFS minifilter's filter-port connect callback. A client
connects to the ProjFS communication port and passes a `_PRJ_CONNECTION_CONTEXT`
that contains a **`VolumeLength`** field and an inline **`szVolume`** name (a
**`WCHAR`** string). `PrjfPortConnect` validates that `szVolume` fits inside the
supplied context, then builds a `UNICODE_STRING` from it and passes it to
`PrjfGetInstanceFromVolumeName` → `FltGetVolumeFromName` → `ZwCreateFile`.

---

## Vulnerability Summary

The size check treated the `WCHAR` volume name as if it were a **byte** array:

```c
// PrjfPortConnect (10.0.26100.8115) — PRE-PATCH, from the reporter analysis
if ( SizeOfContext >= ConnectionContext->VolumeLength + 0x16 ) {   // *** VolumeLength (WCHAR count) not doubled ***
    ...
    // build usVolumeName from szVolume (WCHAR) and call PrjfGetInstanceFromVolumeName(&usVolumeName, &Instance)
}
```

`szVolume` is a `WCHAR` array, so its byte size is `VolumeLength * 2`, and the
correct bound is `SizeOfContext >= VolumeLength * 2 + 0x16`. Because pre-patch only
required `VolumeLength + 0x16`, a client can declare a `VolumeLength` up to ~2× the
real space, so the `UNICODE_STRING` built from `szVolume` (length in bytes derived
from `VolumeLength`) **extends past the end of the connection-context buffer**. That
over-read `UNICODE_STRING` is then used as the `ObjectName` for `ZwCreateFile`,
reading out-of-bounds kernel pool memory (CWE-126) — an information-disclosure /
corruption primitive usable for EoP.

---

## Prerequisites and Constraints

- Local, low-privileged (`PR:L`, `AV:L`, `AC:L`): connect to the ProjFS filter port
  with a crafted `_PRJ_CONNECTION_CONTEXT`.
- Set `VolumeLength` large enough that `VolumeLength*2` exceeds the remaining
  context space while `VolumeLength + 0x16` still passes the pre-patch check.
- Result: the `szVolume` `UNICODE_STRING` reads past the context buffer and is used
  as a file `ObjectName`.

---

## Vulnerability Details

### Root Cause

The bounds check used `VolumeLength` (a `WCHAR` **count**) directly as a **byte**
length, under-validating the inline `szVolume` by a factor of two, so the derived
`UNICODE_STRING` could reference memory beyond the connection context.

### The patch (confirmed — diff, .8115 → .8246)

Gated behind `Feature_3411221816`, `PrjfPortConnect` **doubles `VolumeLength`**
(WCHAR → bytes) before the bounds check:

```c
// PrjfPortConnect (10.0.26100.8246) — PATCHED, feature-enabled branch (from our diff)
sVar5 = ConnectionContext->VolumeLength;
if ( Feature_3411221816__private_IsEnabledDeviceUsage() ) {
    if ( (ushort)(sVar5 - 1) < 0x7fff )
        sVar5 = sVar5 * 2;                 // *** WCHAR count -> byte length ***
}
// then require SizeOfContext >= sVar5 + 0x16
```

With the length doubled, the check requires the full byte size of `szVolume`, so a
name that would run past the context is rejected — closing the over-read. (An
overflow guard `(ushort)(sVar5 - 1) < 0x7fff` prevents the ×2 itself from wrapping.)

### Patch Completeness Assessment

**CFR-gated behind `Feature_3411221816`.** The doubled-length check runs only when
the flag is enabled; the original under-validating check still ships when disabled.
Verify `Feature_3411221816` is enabled to confirm the fix is live.

---

## Detection Guidance

**Behavioural.** ProjFS filter-port connections whose `_PRJ_CONNECTION_CONTEXT`
declares a `VolumeLength` near the context-size boundary; `ZwCreateFile` /
`FltGetVolumeFromName` calls from `prjflt!PrjfGetInstanceFromVolumeName` with
malformed volume names; over-read / pool-read crashes on unpatched/flag-disabled
builds.

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

---

## References

- MSRC advisory — CVE-2026-26184 (Windows Projected File System Elevation of Privilege), released 2026-04-14, KB5083769.
- Full binary diff: `/data/patch_diffs/prjflt_sys-cve-2026-26184-ghidriff.md`
- Related same-KB ProjFS fixes: CVE-2026-32074, CVE-2026-32078, CVE-2026-27927.
