# CVE-2026-42968 — Windows Telephony Server `tapisrv.dll` Out-of-Bounds Read: Unbounded Sub-Mask Index in Event-Mask Array Access

---

## Summary

| | |
|---|---|
| **Product** | Windows — `tapisrv.dll` (Telephony Server / TAPI event-mask handling) |
| **CVE ID** | CVE-2026-42968 |
| **Impact** | Information Disclosure |
| **MSRC severity** | Important |
| **CVSS** | 5.5 / 4.8 — `CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N/E:U/RL:O/RC:C` |
| **CWE** | CWE-125: Out-of-bounds Read |
| **Delivery** | Local — a crafted TAPI request over the Telephony Server RPC interface; the OOB DWORD is returned in the RPC response |
| **KB / Fixed build** | KB5094126 — `tapisrv.dll` 10.0.26100.8655 (Win11 24H2 x64) |
| **Patch Date** | June 9, 2026 (2026-Jun) |
| **Pre-patch binary** | `tapisrv.dll` 10.0.26100.8521 — SHA256 `be01d3bd28d2e12d81690790d3a68fbab6814a97b650a1534a9e73ad5ed5a01e` |
| **Post-patch binary** | `tapisrv.dll` 10.0.26100.8655 — SHA256 `c00c8f51b6ba0bbd76927ac6eefb399a62e5e20fbbe41bdb45ef5901a8a1f169` |
| **Feature flag** | `Feature_500158777` (+ `Feature_784066872`) — **the fix is CFR-gated** |
| **Exploitability** | Exploitation Less Likely; not publicly disclosed; not exploited (per MSRC) |

---

## Product Description

`tapisrv.dll` is the Windows **Telephony Server**. TAPI tracks event state for
several object kinds (client, call client, line client, phone client, line
application, phone application) as a **DWORD array of 31 entries** (valid index
0–30). The whole-mask processing path walks each array exactly 31 times, and the
post-patch bound `0x1F` matches that size. Because the surface is reachable by a
local, low-privileged caller over RPC and results are returned in the RPC
response, an out-of-bounds read here discloses adjacent kernel/service memory.

---

## Vulnerability Summary

In **single sub-mask mode** (`request+0x10 != 0`), the handler combines the two
DWORDs at `request+0x18` / `request+0x1C` into a **64-bit sub-mask**, then derives
an array index from the position of the highest set bit
(`idx = floor(log2(submask))`, via `GetSubMaskIndex`). Pre-patch there is **no
check that `idx` fits the 31-entry array**:

```c
// GetEventMasksOrSubMasks / SetEventMasksOrSubMasks (10.0.26100.8521) — PRE-PATCH, from our diff
uVar1 = GetSubMaskIndex(param_2);   // idx = floor(log2(64-bit submask)) — can be up to 63
*param_4 = param_5[uVar1];          // READ path: base[idx]  (no bound)
// ... and on the write path:
param_4[uVar1] = param_3;           // WRITE path: base[idx] = value  (no bound)
```

Because the sub-mask is 64-bit, a client that sets only bit 63 yields `idx = 63`.
The array has 31 slots (last valid `base[30]`), so `base[63]` is 33 DWORDs — **132
bytes** — past the last valid entry. On the read path (`TGetEventMasksOrSubMasks`)
that out-of-bounds DWORD is stored into the return field `request+0x14` and
returned to the caller as an RPC response — a 4-byte disclosure of adjacent TAPI
object memory (CWE-125). The identical index is used on the write path
(`SetEventMasksOrSubMasks`, reached from the six per-object setters), giving a
matching out-of-bounds write primitive.

---

## Prerequisites and Constraints

- Local, low-privileged (`PR:L`, `AV:L`). The attacker sends a crafted TAPI
  request to the Telephony Server RPC interface.
- Trigger: single sub-mask mode with a sub-mask whose highest set bit is above
  bit 30 (e.g. bit 63 → `idx = 63`).
- Read path leaks 4 bytes per request (`C:H`); the same unbounded index also
  reaches an out-of-bounds array write on the set path.

---

## Vulnerability Details

### Root Cause

`GetSubMaskIndex` can return an index up to 63 from a 64-bit sub-mask, but the
event-mask array holds only 31 entries. Neither the read helper nor the write
helper validated the index against the array size before dereferencing
`base[idx]`, so an attacker-chosen high bit drives the access far past the array.

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

A single index upper-bound check is added at every array-access point, gated
behind `Feature_500158777` (the read path's `TGetEventMasksOrSubMasks` also
references `Feature_784066872`). If the feature is on and `idx >= 0x1F` (31), the
function refuses the access and returns `0x80000032` instead of touching the
array:

```c
// GetEventMasksOrSubMasks / SetEventMasksOrSubMasks (10.0.26100.8655) — PATCHED, feature-enabled branch
uVar1 = GetSubMaskIndex(param_2);
uVar2 = Feature_500158777__private_IsEnabledDeviceUsageNoInline();
if ((uVar2 != 0) && (0x1e < uVar1)) {   // *** idx >= 31 -> reject ***
    return 0x80000032;
}
*param_4 = param_5[uVar1];              // (read)  / param_4[uVar1] = param_3; (write)
```

The check is placed at **7 access points**: the six per-object read accesses of
`TGetEventMasksOrSubMasks` (refactored through the new `GetEventMasksOrSubMasks`
helper) and the common `SetEventMasksOrSubMasks` write access. The whole-mask
path already walked the array exactly 31 times (`lVar = 0x1f` loop counter) and is
unchanged.

### Patch Completeness Assessment

**CFR-gated behind `Feature_500158777` / `Feature_784066872`.** The bound runs
only when the flags are enabled; the original unchecked access still ships in
.8655. Patch state is not determined by file version alone — the runtime-gated
pattern seen across this corpus. Verify the flags are enabled to confirm the
bound is live.

---

## Detection Guidance

**Behavioural.** TAPI single-sub-mask requests carrying a sub-mask with a set bit
above bit 30 (index > 30); Telephony Server RPC responses returning event-mask
DWORDs for such requests on unpatched/flag-disabled builds.

**Crash signature.** On the write path, pool corruption attributable to
`tapisrv!SetEventMasksOrSubMasks` writing past a 31-entry event-mask array.

**Config.** The fix is CFR-gated — confirm `Feature_500158777` (and
`Feature_784066872`) are enabled so the `>= 0x1F` bound is active.

---

## References

- MSRC advisory — CVE-2026-42968 (Windows Telephony Server Information Disclosure), released 2026-06-09, KB5094126.
- Full binary diff: `/data/patch_diffs/tapisrv_dll-cve-2026-42968-ghidriff.md`
- Related Telephony bugs: CVE-2024-43518 (tapi32.dll GrowBuf).
