# CVE-2025-24056 — Windows Telephony Service `tapisrv.dll` Priority-List Allocation Integer Overflow → Heap Buffer Overflow (RCE)

---

## Summary

| | |
|---|---|
| **Product** | Windows — `tapisrv.dll` (Windows Telephony Service / TAPI Server) |
| **CVE ID** | CVE-2025-24056 |
| **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-122: Heap-based Buffer Overflow (via integer overflow) |
| **Delivery** | Network — client is tricked into connecting to a malicious telephony server (`UI:R`) |
| **KB / Fixed build** | KB5053598 — `tapisrv.dll` 10.0.26100.3323 (Win11 24H2 x64) |
| **Patch Date** | March 11, 2025 (2025-Mar) |
| **Pre-patch binary** | `tapisrv.dll` 10.0.26100.3037 — SHA256 `7cde3632cc64c832593ce03e3d5f61eb22fb12253af2a35d618e36efcdb378db` |
| **Post-patch binary** | `tapisrv.dll` 10.0.26100.3323 — SHA256 `c0fbaec69f5495be56c3d4de2a56aa55a538171600024d8be084a8a7e6fa6ce2` |
| **Feature flag** | `Feature_1390216506` — gated the check pre-patch; the fixed build makes it unconditional |
| **Exploitability** | Exploitation Less Likely; not publicly disclosed; not exploited (per MSRC) |

---

## Product Description

`tapisrv.dll` implements the **Windows Telephony Service (TAPI Server)**. It builds
**media-mode / application priority lists** from configuration values via
`GetPriorityList`, `GetMediaModesPriorityLists`, and `LSetAppPriority`. Each reads a
priority-list value into a heap buffer allocated from the TAPI heap
(`HeapAlloc(ghTapisrvHeap, …)`), prefixing a quote character and reserving two extra
bytes for a wide-char terminator.

---

## Vulnerability Summary

The priority-list readers size the destination buffer as `value_size + 2` and pass
that to `HeapAlloc`, then fill it with `value_size` bytes (`RegQueryValueExW`). When
the check on the size was **bypassable** (see below), a `value_size` near
`0xFFFFFFFF` would make `value_size + 2` **wrap to a tiny value** (CWE-190), producing
an **undersized heap allocation** that is then overrun by the full-size read — a
heap-based buffer overflow (CWE-122). Because the Telephony Service processes data on
behalf of a telephony server the client connects to, MSRC classifies this as remote
code execution on the client that connects to a **malicious server** (`AV:N`,
`UI:R`).

> Confirmation level: the diff is a broad `tapisrv.dll` priority-list rework (4
> code-changed functions, 20 modified, 25 removed) under the flag `Feature_1390216506`.
> The isolable security mechanism is the **`value_size <= value_size + 2` integer-
> overflow guard on the priority-list allocation**, which the fixed build enforces
> unconditionally; stated here at confirmed-changed level.

---

## Prerequisites and Constraints

- Network with user interaction (`AV:N`, `PR:N`, `UI:R`): the victim's client is
  induced to connect to a malicious telephony server that supplies the oversized
  priority-list data.
- The size driving `HeapAlloc(value_size + 2)` is near `UINT_MAX` so the `+ 2` wraps.
- Result: an undersized TAPI-heap buffer is allocated and then overrun.

---

## Vulnerability Details

### Root Cause

The priority-list allocation size `value_size + 2` was computed without an
always-enforced overflow check, so a near-`UINT_MAX` size wrapped to a small
allocation that was subsequently overrun by a full-size copy.

### The patch (confirmed — diff, .3037 → .3323)

Pre-patch, the overflow check in the priority-list readers was **gated behind
`Feature_1390216506` and bypassable when the flag was disabled**:

```c
// GetMediaModesPriorityLists (10.0.26100.3037) — PRE (from the diff)
if ( ... && (Feature_1390216506__private_IsEnabled() == 0
             || (value_size <= value_size + 2)) ) {           // check skipped when flag OFF
    _Str = HeapAlloc(ghTapisrvHeap, 8, (ulonglong)(value_size + 2));
    ...
}
```

The fixed build enforces the `value_size <= value_size + 2` guard **unconditionally**
(no feature bypass) before the allocation and copy:

```c
// GetPriorityList / GetMediaModesPriorityLists (10.0.26100.3323) — PATCHED (from the diff)
if ((LVar1 == 0) && (value_size != 0)) {
    if (value_size <= value_size + 2) {                        // *** overflow guard, always enforced ***
        _Str = HeapAlloc(ghTapisrvHeap, 8, (ulonglong)(value_size + 2));
        if (_Str != NULL) {
            *_Str = L'\"';
            LVar1 = RegQueryValueExW(param_1, param_2, NULL, local_res20, (LPBYTE)(_Str + 1), &value_size);
            if ((LVar1 == 0) && (1 < value_size)) {
                *(WCHAR*)((longlong)_Str + ((value_size - 2) & ~1) + 2) = 0;   // bounded terminator
                ...
            } else ServerFree(_Str);
        }
    }
}
```

With the overflow guard always enforced, a wrapped `value_size + 2` no longer yields
an undersized allocation, so the priority-list buffer can no longer be overrun,
closing the integer-overflow-to-heap-overflow. (`LSetAppPriority` similarly gains a
bounded `0x104`/MAX_PATH length handling for the app-name string.)

### Patch Completeness Assessment

The guard is **enforced unconditionally in the fixed build** (`Feature_1390216506`
previously allowed the check to be skipped). Apply KB5053598 or later; the flag no
longer needs to be enabled for the fix to be active on the patched binary.

---

## Detection Guidance

**Behavioural.** Heap corruption / crashes in `tapisrv!GetPriorityList` /
`GetMediaModesPriorityLists` / `LSetAppPriority` within the Telephony Service on
unpatched builds; clients connecting to untrusted telephony servers. Restrict TAPI
usage and outbound telephony connections to trusted endpoints.

**Config.** In the fixed build the guard is unconditional; on the pre-patch build it
depended on `Feature_1390216506`.

---

## References

- MSRC advisory — CVE-2025-24056 (Windows Telephony Service Remote Code Execution), released 2025-03-11, KB5053598.
- Full binary diff: `/data/patch_diffs/tapisrv_dll-cve-2025-24056-ghidriff.md`
