# CVE-2025-21201 — Windows Telephony Service `remotesp.tsp` Remote-Response Double Free (Malicious-Server RCE)

---

## Summary

| | |
|---|---|
| **Product** | Windows — `remotesp.tsp` (TAPI Remote Service Provider / Windows Telephony Server) |
| **CVE ID** | CVE-2025-21201 |
| **Impact** | Remote Code Execution (on a client that connects to a malicious telephony 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-415: Double Free |
| **Delivery** | Network — client connects to a malicious telephony server (`UI:R`) |
| **KB / Fixed build** | KB5051987 — `remotesp.tsp` 10.0.26100.3194 (Win11 24H2 x64) |
| **Patch Date** | February 11, 2025 (2025-Feb) |
| **Pre-patch binary** | `remotesp.tsp` 10.0.26100.2894 — SHA256 `8320b77fe2971811a9a2b8a8fd8f22b5c89857db4ed2a6d1f7417100063c33eb` |
| **Post-patch binary** | `remotesp.tsp` 10.0.26100.3194 — SHA256 `eeebcd76fc0f83ed06c8689ee7e46751a75de56dbf96b92d6752828bb1ec4f0a` |
| **Feature flag** | `Feature_2332850489` — **the fix is CFR-gated** |
| **Exploitability** | Exploitation Less Likely; not publicly disclosed; not exploited (per MSRC) |

> Binary note: the "Windows Telephony Server" fix for this CVE is in **`remotesp.tsp`**,
> not `tapisrv.dll` — `tapisrv.dll`/`tapi32.dll` were unchanged (10.0.26100.3037) across
> the Jan→Feb updates, while `remotesp.tsp` went `.2894 → .3194` (KB5051987), matching
> the MSRC fixed build exactly.

---

## Product Description

`remotesp.tsp` is the **TAPI Remote Service Provider** — the client-side telephony
service provider that issues async requests to a remote telephony server and processes
the server's responses. `RemoteDoFunc` dispatches a server response: it walks the
returned per-request records and copies each record's returned data back into the
corresponding client-side request buffer.

---

## Vulnerability Summary

`RemoteDoFunc` processes a response supplied by the (potentially malicious) remote
telephony server and applies each returned record to a client-side outstanding-request
buffer selected from an array (`client_buf[slot]`). Pre-patch, a returned record was
applied to its slot **without verifying that it actually corresponded to that
outstanding request**. A crafted server response could therefore drive the client to
apply a mismatched/duplicate completion to a request buffer — reprocessing (and
re-releasing) a buffer whose lifetime had already ended — a **double free (CWE-415)**.
Because the client parses attacker-controlled server data over the network (`AV:N`,
`UI:R` — the user must connect to the malicious server), the double free is a remote
code-execution primitive on the client.

> Confirmation level: the diff (self-generated from the two Microsoft symbol-server
> builds) shows `RemoteDoFunc` reworked under `Feature_2332850489`; the isolable
> security mechanism is the **added identity check that a returned record matches its
> target request buffer before it is applied**. Stated here at confirmed-changed level.

---

## Prerequisites and Constraints

- Network with user interaction (`AV:N`, `PR:N`, `UI:R`): the victim's telephony client
  connects to a malicious server (e.g., is tricked into a remote TAPI session).
- The server returns a crafted response whose per-request records do not correspond to
  the client's outstanding requests.
- Result (pre-patch): a request buffer is reprocessed/re-released → double free.

---

## Vulnerability Details

### Root Cause

`RemoteDoFunc` applied server-returned records to client request buffers without
confirming a returned record belonged to the request buffer it was written to, so a
crafted server response could cause the same buffer to be freed twice.

### The patch (confirmed — diff, .2894 → .3194)

Gated behind `Feature_2332850489`, `RemoteDoFunc` adds an **identity check**: before
copying a returned record into a client buffer, it verifies that the record's leading
field matches the target buffer's leading field, and **fails the operation
(`0x80000048`)** on mismatch:

```c
// RemoteDoFunc (10.0.26100.3194) — PATCHED (from the diff)
if (Feature_2332850489__private_IsEnabled()
        && (*returned_record != **(uint **)(client_buf_array[slot]))) {   // *** identity check ***
    return 0x80000048;                                                    // reject mismatched record
}
len = returned_record[2];
memcpy(client_buf_array[slot], returned_record, len);                     // apply only matching record
```

Pre-patch, the returned record was applied to the slot with no such check, so a
mismatched/duplicate server record could be routed to a request buffer it did not own,
driving the double free. With the identity check, only a record that matches its
target outstanding request is applied; mismatched server responses are rejected,
closing the double free.

### Patch Completeness Assessment

**CFR-gated behind `Feature_2332850489`.** The identity check runs only when the flag
is enabled; the original unchecked handling remains when disabled. Verify
`Feature_2332850489` is enabled to confirm the fix is live. Given RCE from a malicious
server, apply KB5051987 or later regardless.

---

## Detection Guidance

**Behavioural.** Heap corruption / double-free crashes in `remotesp!RemoteDoFunc`
within the telephony client after connecting to a remote telephony server; clients
initiating remote TAPI sessions to untrusted servers. Restrict remote TAPI /
telephony connections to trusted endpoints.

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

---

## References

- MSRC advisory — CVE-2025-21201 (Windows Telephony Server Remote Code Execution), released 2025-02-11, KB5051987.
- Full binary diff: `/data/patch_diffs/remotesp_tsp-cve-2025-21201-ghidriff.md`
