# CVE-2026-27927 — Windows Projected File System `prjflt.sys` AVL Handle-Table Entry Lifetime Race in `PrjfCopyStreamData` → Use-After-Free

---

## Summary

| | |
|---|---|
| **Product** | Windows — `prjflt.sys` (Windows Projected File System / ProjFS minifilter) |
| **CVE ID** | CVE-2026-27927 |
| **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-362 Race Condition + CWE-416 Use After Free |
| **Delivery** | Local race — concurrent operations on a ProjFS placeholder during stream-data expansion |
| **KB / Fixed build** | KB5083769 — `prjflt.sys` 10.0.26100.8246 (Win11 24H2 x64) |
| **Patch Date** | April 14, 2026 (2026-Apr) |
| **Pre-patch binary (baseline)** | `prjflt.sys` 10.0.26100.4202 — SHA256 `ffb5ab23d8174ced2af4267efd9e94dff3ce0c337a1444e7b8d4ac66eb205de7` |
| **Post-patch binary** | `prjflt.sys` 10.0.26100.8246 — SHA256 `6eeb5961eb44704a1515a3df15bbf02ce4e63c55b46fb00158a5d65c7b4fd555` |
| **Exploitability** | Exploitation Less Likely; not publicly disclosed; not exploited (per MSRC) |

> Confirmation: our in-house diff of `prjflt.sys` confirms `PrjfCopyStreamData` is
> among the code-changed functions in the fix; the precise synchronization
> instruction is heavily inlined and not cleanly isolable in the decompiled
> wide-span diff, so the mechanism below follows the reporter PoC.

---

## Product Description

`PrjfCopyStreamData` runs on the ProjFS expansion worker
(`PrjfExpansionWorker` → `PrjfExpandFile` → `PrjfCopyStreamData`). It tracks the
in-flight file via a per-union-context **AVL handle table**
(`UnionContext->AvlHandleTable`) whose entries are
`_PRJ_HANDLE_AVL_TABLE_ENTRY { UUID FileId; PFILE_OBJECT FileObject; HANDLE FileHandle; }`,
keyed by `FileId` (from `StreamContext->Uuid`). The `FileObject` comes from
`FltObjects->FileObject`.

---

## Vulnerability Summary

`PrjfCopyStreamData` inserts the handle entry, references the `FILE_OBJECT`, then
sends a **user-mode command** and only afterwards removes the entry and drops the
reference:

```c
// PrjfCopyStreamData — from the reporter PoC
InsertedEntry = RtlInsertElementGenericTableAvl(&UnionContext->AvlHandleTable,
                                                &HandleEntry, 0x20, &bNewElement);
if (InsertedEntry) {
    if (bNewElement) ObfReferenceObject(HandleEntry.FileObject);   // ref +1 on new entry
    ...
    Status = PrjfSendGetFileStreamCommand(Instance, FileObject, &Offset, Length);  // *** user-mode round-trip ***
    ...
    RtlDeleteElementGenericTableAvl(&UnionContext->AvlHandleTable, &HandleEntry);   // remove entry
    if (bNewElement) ObDereferenceObjectDeferDelete(HandleEntry.FileObject);        // ref -1
}
```

`PrjfSendGetFileStreamCommand` sends a message to the user-mode ProjFS provider and
**waits** — a long window during which another thread can operate on the **same
`FileId` / AVL entry** without adequate synchronization. The shared AVL-table entry
(and the `FILE_OBJECT` it references) can be removed/freed or have its reference
state changed concurrently, so this path then uses / dereferences an entry or
object that no longer has a valid lifetime — a race-induced **use-after-free**
(CWE-362 → CWE-416). It runs in the SYSTEM expansion worker, so it is a local EoP.

---

## Prerequisites and Constraints

- Local, low-privileged (`PR:L`, `AV:L`, `AC:L`): open/expand ProjFS placeholder
  files to drive `PrjfCopyStreamData`, and race concurrent operations on the same
  `FileId` during the user-mode `PrjfSendGetFileStreamCommand` window.
- Winning the race leaves the AVL entry / `FILE_OBJECT` freed while this path still
  uses it.

---

## Vulnerability Details

### Root Cause

The AVL handle-table entry's lifetime (and the referenced `FILE_OBJECT`) was not
adequately synchronized across the blocking user-mode `PrjfSendGetFileStreamCommand`
call, so a concurrent operation on the same key could free/alter it mid-use.

### The patch (confirmed changed — diff to .8246)

Our in-house diff confirms `PrjfCopyStreamData` is reworked in the April fix
(KB5083769, `prjflt.sys` .8246). Consistent with the reporter analysis, the fix
serializes the AVL handle-table entry lifetime against concurrent access across the
user-mode command round-trip (so the entry and its referenced `FILE_OBJECT` cannot
be freed while this path is still using them), closing the race. (Like the other
April ProjFS fixes in this driver, the change is CFR-gated.)

### Patch Completeness Assessment

Fixed in `prjflt.sys` 10.0.26100.8246 (April 2026). Apply KB5083769.

---

## Detection Guidance

**Behavioural.** Concurrent ProjFS placeholder expansion / access on the same
virtualized file during stream-data fetch; UAF / pool-corruption bugchecks in
`prjflt!PrjfCopyStreamData` / `PrjfExpandFile` / AVL-table handling on unpatched
builds.

---

## References

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