# CVE-2026-58594 — Remote Desktop Client `mstscax.dll` Frame-Buffer Size Integer Overflow → Heap Buffer Overflow (Malicious-Server RCE)

---

## Summary

| | |
|---|---|
| **Product** | Windows — `mstscax.dll` (Remote Desktop Client / RDP ActiveX control) |
| **CVE ID** | CVE-2026-58594 |
| **Impact** | Remote Code Execution (on a client that connects to a malicious RDP server) |
| **MSRC severity** | Important |
| **CVSS** | 8.8 / 7.7 — `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H/E:U/RL:O/RC:C` |
| **CWE** | CWE-190: Integer Overflow or Wraparound (→ heap buffer overflow) |
| **Delivery** | Network — victim connects an RDP client to an attacker-controlled server |
| **KB / Fixed build** | KB5101650 — `mstscax.dll` 10.0.26100.8875 (Win11 24H2 x64) |
| **Patch Date** | July 14, 2026 (2026-Jul) |
| **Pre-patch binary** | `mstscax.dll` 10.0.26100.8737 — SHA256 `3dd509e2b63b67d1e6d34fe611173df124123725b584826b119945612cae7811` |
| **Post-patch binary** | `mstscax.dll` 10.0.26100.8875 — SHA256 `bcc2cbfeaf8bdbb706be11887f22641943c57a23ad5b463e42e83f38ae54b49a` |
| **Feature flag** | `Feature_2141685050` — **the fix is CFR-gated** |
| **Exploitability** | Exploitation Less Likely; not publicly disclosed; not exploited (per MSRC) |

> Cross-checked against an independent writeup — the vulnerable expression, the diagnostic
> string, and the 64-bit-product fix match the ghidriff. (The writeup cites
> `Feature_2208793915`; the analysed ghidriff gates the fix in `SurfaceDecoderCpu::Init` with
> `Feature_2141685050`.) A related lower-bound guard was also added in `CaCpuDecompressor`;
> the frame-buffer overflow for this CVE is the `SurfaceDecoderCpu::Init` change.

---

## Product Description

`mstscax.dll` is the Remote Desktop **client** control. When decoding server-supplied graphics
it allocates a CPU **frame/surface buffer** sized from the server-advertised surface
**width × height** (× 4 bytes/pixel) in `CacNx::SurfaceDecoderCpu::Init`.

---

## Vulnerability Summary

Pre-patch, the frame-buffer allocation size was computed as `4 * width * height` in **32-bit
arithmetic**. A malicious RDP **server** can advertise surface dimensions whose product
overflows 32 bits, so `malloc` receives a **wrapped, undersized size** while the client later
writes a full-size surface into it — an integer overflow (CWE-190) leading to a heap buffer
overflow. Because the client parses attacker-controlled server data over the network (`AV:N`,
`PR:N`, `UI:R` — the user must connect to the server), the overflow is a remote code-execution
primitive on the client (Microsoft rates it **Important, 8.8**).

---

## Prerequisites and Constraints

- Network with user interaction (`AV:N`, `PR:N`, `UI:R`): the victim connects an RDP client to
  an attacker-controlled server.
- The server advertises surface `width × height` whose 32-bit `× 4` product overflows.
- Result: an undersized frame buffer is allocated and then overrun during decode.

---

## Vulnerability Details

### Root Cause

`width * height * 4` was evaluated in 32-bit before being passed to `malloc`, so a
server-chosen dimension product could wrap to a small value, undersizing the frame buffer.

### The patch (confirmed — diff, .8737 → .8875)

Gated behind `Feature_2141685050`, `CacNx::SurfaceDecoderCpu::Init` computes the size as a
**64-bit product** (each dimension cast to `longlong`) and **rejects a zero/overflowed size**
before allocating:

```c
// CacNx::SurfaceDecoderCpu::Init (10.0.26100.8875) — PATCHED (from the diff)
if (Feature_2141685050__private_IsEnabled()) {
    _Size = (longlong)*(int*)(param_2 + 4) * (longlong)*(int*)param_2 * 4;   // *** 64-bit: height * width * 4 ***
    if (_Size == 0) {
        // WPP_SF_Sd(..., L"\"Frame buffer allocation size overflow or zero\"", ...);
        // return E_INVALIDARG (0x80070057)
    }
    free(*(void**)(this + 0xe0));
    pvVar5 = malloc(_Size);                       // allocate the full 64-bit size
}
// else: legacy 32-bit  4 * width * height
```

Pre-patch the multiplication happened in 32 bits (`malloc(4 * width * height)`); post-patch the
dimensions are widened to 64-bit before multiplying, so an overflowing product no longer wraps
to a small allocation, and a zero/overflow result is rejected with
`"Frame buffer allocation size overflow or zero"`, closing the overflow. (A separate lower-bound
guard on decoder dimensions was added in `CaCpuDecompressor` in the same update.)

### Patch Completeness Assessment

**CFR-gated behind `Feature_2141685050`.** The 64-bit size computation and zero check run only
when the flag is enabled; the original 32-bit multiply still ships when disabled. Verify the
flag is enabled to confirm the fix is live. The zero check rejects an overflowed-to-zero size
but does not itself bound negative dimensions — that lower bound is enforced by the companion
`CaCpuDecompressor` guard.

---

## Detection Guidance

**Behavioural.** Heap-corruption crashes in the RDP client
(`mstscax!CacNx::SurfaceDecoderCpu::Init` / the CPU decompressor) when connecting to a server on
unpatched/flag-disabled builds; connecting to untrusted RDP servers. Restrict outbound RDP to
trusted endpoints.

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

---

## References

- MSRC advisory — CVE-2026-58594 (Remote Desktop Client Remote Code Execution), released 2026-07-14, KB5101650.
- Full binary diff: `/data/patch_diffs/mstscax_dll-cve-2026-58594-ghidriff.md`
