# CVE-2026-40409 — Windows UDFS `udfs.sys` 64→32-bit VBN Truncation in `UdfGetBlocksNeeded`

---

## Summary

| | |
|---|---|
| **Product** | Windows — `udfs.sys` (Universal Disk Format File System driver) |
| **CVE ID** | CVE-2026-40409 |
| **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-197: Numeric Truncation Error |
| **Delivery** | Local — a crafted UDF image (`.iso` / `.img` / UDF VHD) mounted or opened |
| **KB / Fixed build** | KB5094126 — `udfs.sys` 10.0.26100.8655 (Win11 24H2 x64) |
| **Patch Date** | June 9, 2026 (2026-Jun) |
| **Pre-patch binary** | `udfs.sys` 10.0.26100.8521 — SHA256 `b177af321fdb4ff6907f05b028e7ac33486c2000dbc1e75c4bed848f84e164c6` |
| **Post-patch binary** | `udfs.sys` 10.0.26100.8655 — SHA256 `2a9b930ad0ccb43fc6b31cb8a600cb026bb5dea9ccf79c28c7d311d65e62be99` |
| **Feature flag** | `Feature_3105867064` — **the fix is CFR-gated** |
| **Exploitability** | Exploitation Less Likely; not publicly disclosed; not exploited (per MSRC) |

---

## Product Description

`UdfGetBlocksNeeded` converts a file's 64-bit byte offset / length into a logical
block or sector number by right-shifting by `Vcb->LBSizeShift` (`Vcb + 0x48`), and
computes the number of blocks needed for a run of I/O.

---

## Vulnerability Summary

The converted result can exceed the 32-bit range, but pre-patch the code used it in
a **32-bit** slot without an upper-bound check. When a 64-bit offset/length is large
enough that it does not fit in 32 bits **even after** the `LBSizeShift` right-shift,
the **upper bits are silently dropped**, yielding a block/sector number **smaller
than the real value** (CWE-197).

That truncated value flows into a disk-I/O **sector count** or into the **VBN** of
an MCB mapping, so the logical→physical sector correspondence becomes misaligned or
the on-disk extent is computed too small — the same under-mapping that leads to
out-of-bounds kernel access when the real-size I/O runs.

---

## Prerequisites and Constraints

- Local, low-privileged (`PR:L`, `AV:L`, `AC:L`): auto-mount/open a crafted UDF
  image, or reach a write path that calls `UdfGetBlocksNeeded`.
- The offset/length is chosen so the block-converted value overflows 32 bits.
- Result: truncated VBN/sector count → misaligned/under-sized extent mapping.

---

## Vulnerability Details

### Root Cause

A 64-bit offset/length was converted to a block unit and consumed as 32 bits with
no range check, so the high bits were truncated and downstream VBN/sector counts
were smaller than the true values.

### The patch (confirmed — diff, .8521 → .8655)

Gated behind `Feature_3105867064`, an upper-bound check is added right before the
conversion: if the input offset/length (`*a3`) is **negative** or exceeds
`0xFFFFFFFF << LBSizeShift`, it aborts with `ExRaiseStatus`:

```c
// UdfGetBlocksNeeded (10.0.26100.8655) — PATCHED, feature-enabled branch (from our diff)
if ( (longlong)*param_3 < 0
  || (0xffffffffL << (Vcb->LBSizeShift & 0x3f)) < *param_3 )
    ExRaiseStatus(0xC000000D);   // STATUS_INVALID_PARAMETER
```

`0xFFFFFFFF << LBSizeShift` is the maximum byte value that still yields a valid
32-bit VBN/sector count after the shift, so the truncated value can no longer flow
into `FsRtlAddLargeMcbEntry` as a VBN or into a sector count.

### Patch Completeness Assessment

**CFR-gated behind `Feature_3105867064`.** The bound runs only when the flag is
enabled; the original truncating path still ships when disabled. Verify the flag is
enabled to confirm the fix is live. (Related same-KB UDFS fix: CVE-2026-40404 in
`UdfInitializeAllocations`, gated by `Feature_2146947386`.)

---

## Detection Guidance

**Behavioural.** Mounting/opening UDF images with file offsets/lengths near/over the
32-bit block boundary; UDFS returning `STATUS_INVALID_PARAMETER` for such requests
once the fix is active; misaligned-extent / OOB access crashes in
`udfs!UdfGetBlocksNeeded` on unpatched/flag-disabled builds.

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

---

## References

- MSRC advisory — CVE-2026-40409 (Windows UDFS Elevation of Privilege), released 2026-06-09, KB5094126.
- Full binary diff: `/data/patch_diffs/udfs_sys-cve-2026-40404-40409-ghidriff.md`
