# CVE-2025-59196 — Windows SSDP Service `ssdpsrv.dll` Notify-Semaphore List Race → Use-After-Free

---

## Summary

| | |
|---|---|
| **Product** | Windows — `ssdpsrv.dll` (SSDP Discovery Service / Simple Search and Discovery Protocol) |
| **CVE ID** | CVE-2025-59196 |
| **Impact** | Elevation of Privilege (to SYSTEM) |
| **MSRC severity** | Important |
| **CVSS** | 7.0 / 6.1 — `CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H/E:U/RL:O/RC:C` |
| **CWE** | CWE-362: Race Condition → CWE-416: Use After Free |
| **Delivery** | Local — win a race on the SSDP notify-semaphore list |
| **KB / Fixed build** | KB5066835 — `ssdpsrv.dll` 10.0.26100.6899 (Win11 24H2 x64) |
| **Patch Date** | October 14, 2025 (2025-Oct) |
| **Pre-patch binary** | `ssdpsrv.dll` 10.0.26100.6725 (KB5065789) — SHA256 `decdc8645224a2d8e1a5db81f41dd863afc300773baeee421efb2901272e0da6` |
| **Post-patch binary** | `ssdpsrv.dll` 10.0.26100.6899 (KB5066835) — SHA256 `5c00752391f61c52a392e41c249fe632d58401ab4e298453ff8c1b3ce9ee43f4` |
| **Feature flag** | `Feature_3942159674` — **the fix is CFR-gated** |
| **Exploitability** | Exploitation Unlikely; not publicly disclosed; not exploited (per MSRC) |

---

## Product Description

`ssdpsrv.dll` implements the **SSDP Discovery Service**. Its
`CSsdpNotifyRequestManager` tracks per-client **notification semaphores** in a list;
clients register/wait for SSDP notifications through an RPC interface. When a
notification is ready, `_WakeupGetNotificationRpc` signals the client's semaphore
(`ReleaseSemaphore`), and semaphores are removed from the manager's list on teardown
(`HrRemoveNotifySemaphoreFromList`, reached via `_RemoveSyncHandle`).

---

## Vulnerability Summary

The notify-semaphore list and the semaphores it holds are shared across concurrent SSDP
operations (a wakeup/notification path and a removal/teardown path). Pre-patch, these
were **not adequately synchronized**: `_WakeupGetNotificationRpc` could signal
(`ReleaseSemaphore`) a notify semaphore while another thread **removed and freed** that
same semaphore from the list — a race (CWE-362) that yields a use-after-free of the
notify-semaphore object (CWE-416). Because the SSDP service runs at higher privilege
than the caller, winning the race (`AC:H`) allows a local attacker to elevate to
**SYSTEM** (per the MSRC FAQ).

---

## Prerequisites and Constraints

- Local, low-privileged (`AV:L`, `PR:L`); `AC:H` — must win a race between the SSDP
  notification-wakeup path and notify-semaphore removal/teardown.
- Result: a notify semaphore is used (released) after being removed/freed from the
  manager's list.

---

## Vulnerability Details

### Root Cause

Operations on a notify semaphore (signal vs. remove/free) were performed on separate,
unsynchronized paths, so a semaphore could be freed from the list while another thread
still signalled/used it.

### The patch (confirmed — diff, .6725 → .6899)

Gated behind `Feature_3942159674`, the manager consolidates semaphore handling into a
single synchronized method — `HrRemoveNotifySemaphoreFromList` is reworked into
**`HrOperateNotifySemaphoreFromList(sem, _Semaphore_OPERATION)`** — so list membership
and the semaphore operation (release/remove) are performed **atomically under the
manager's synchronization** instead of on independent racy paths:

```c
// PRE (10.0.26100.6725):
//   _WakeupGetNotificationRpc:  ReleaseSemaphore(sem, 1, ...);        // signalled directly
//   HrRemoveNotifySemaphoreFromList(sem);                            // removed/freed on another path -> race

// POST (10.0.26100.6899) — PATCHED (from the diff), gated by Feature_3942159674:
CSsdpNotifyRequestManager::HrOperateNotifySemaphoreFromList(this, sem, operation);
//   single manager method takes a _Semaphore_OPERATION and performs the semaphore
//   action while holding the list synchronized, so signal and remove/free can no
//   longer run concurrently on the same notify semaphore.
```

`_WakeupGetNotificationRpc` and `_RemoveSyncHandle` are updated to route through
`HrOperateNotifySemaphoreFromList` rather than releasing/removing the semaphore
independently. With the operation serialized under the manager, the notify semaphore
can no longer be freed while it is being used, closing the race use-after-free.

### Patch Completeness Assessment

**CFR-gated behind `Feature_3942159674`.** The consolidated synchronized operation runs
only when the flag is enabled; the original independent release/remove paths still ship
when disabled. Verify `Feature_3942159674` is enabled to confirm the fix is live.

---

## Detection Guidance

**Behavioural.** Use-after-free / heap-corruption crashes in the SSDP Discovery service
(`ssdpsrv!CSsdpNotifyRequestManager::HrRemoveNotifySemaphoreFromList` /
`_WakeupGetNotificationRpc` / `_RemoveSyncHandle`) on unpatched/flag-disabled builds,
correlated with concurrent SSDP notification register/wait/teardown activity from
local processes.

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

---

## References

- MSRC advisory — CVE-2025-59196 (Windows SSDP Service Elevation of Privilege), released 2025-10-14, KB5066835.
- Full binary diff: `/data/patch_diffs/ssdpsrv_dll-cve-2025-59196-ghidriff.md`
