CVE-2026-20853 — Windows WalletService Elevation of Privilege Vulnerability
Executive Summary
Concurrent execution using shared resource with improper synchronization ('race condition') in Windows WalletService allows an unauthorized attacker to elevate privileges locally.
Overview
CVSS Vector
CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H/E:U/RL:O/RC:C
EPSS Score
Affected Products
| Product | KB Article | Severity | Impact | Restart Required |
|---|---|---|---|---|
| Windows 10 Version 1607 for 32-bit Systems | 5073722 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 10 Version 1607 for x64-based Systems | 5073722 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 10 Version 1809 for 32-bit Systems | 5073723 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 10 Version 1809 for x64-based Systems | 5073723 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 10 Version 21H2 for 32-bit Systems | 5073724 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 10 Version 21H2 for ARM64-based Systems | 5073724 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 10 Version 21H2 for x64-based Systems | 5073724 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 10 Version 22H2 for 32-bit Systems | 5073724 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 10 Version 22H2 for ARM64-based Systems | 5073724 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 10 Version 22H2 for x64-based Systems | 5073724 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 11 Version 23H2 for ARM64-based Systems | 5073455 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 11 Version 23H2 for x64-based Systems | 5073455 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 11 Version 24H2 for ARM64-based Systems | 5074109 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 11 Version 24H2 for x64-based Systems | 5074109 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 11 Version 25H2 for ARM64-based Systems | 5074109 (Security Update) |
Important | Elevation of Privilege | Yes |
| Windows 11 Version 25H2 for x64-based Systems | 5074109 (Security Update) |
Important | Elevation of Privilege | Yes |
Patches
| Article | Type | Restart |
|---|---|---|
5073722 |
Security Update | Yes |
5073723 |
Security Update | Yes |
5073724 |
Security Update | Yes |
5073455 |
Security Update | Yes |
5074109 |
Security Update | Yes |
Patch Diff
Singleton-teardown race condition (CWE-362 -> use-after-free) in the Windows WalletService WalletService.dll TheWallet singleton, local EoP. TheWallet is a reference-counted singleton with a global instance pointer s_pInstance and a refcount at this+0x48. PRE: TheWallet::Release decrements the count and, when it reaches 0, enters the critical section, re-checks count==0, then UNCONDITIONALLY sets s_pInstance=0 (plain assignment) and destroys the object via vtable[0x50] - without accounting for another thread that re-referenced the object or created a new instance in the window. A concurrent thread that acquired/created the instance is left with a pointer to freed memory (TOCTOU -> UAF). IN-HOUSE ghidriff of WalletService.dll 10.0.26100.7309 -> .7623 (Jan 13 2026, KB5074109) confirms the fix: TheWallet::Release is the only code-changed function; gated behind CFR flag Feature_3403109688, after entering the critical section it double-checks the refcount (if *(this+0x48)!=0 abort) and clears the global pointer with InterlockedCompareExchange64(&s_pInstance, 0, this) (null only if s_pInstance still == this, abort on CAS failure) before destroying the object. Note: our x64 24H2 diff shows Feature_3403109688, differing from the circulated screenshots' Feature_3671545144 (build/arch difference); the double-check + CAS mechanism is identical. We ship what our diff shows.
| Function | Address | Change | Note |
|---|---|---|---|
TheWallet::Release |
code change |
code (double-checked refcount + InterlockedCompareExchange64 on singleton pointer, CFR-gated) | Pre: after refcount hits 0 and entering s_cs, unconditionally s_pInstance=0 (plain assignment) + destroy via vtable[0x50]. Post (Feature_3403109688 enabled): inside the lock, if *(this+0x48)!=0 goto done (abort - another thread re-referenced); LOCK; if (this==s_pInstance){s_pInstance=0;} UNLOCK (InterlockedCompareExchange64(&s_pInstance,0,this)); if CAS failed goto done; destroy only after both checks. Feature-disabled keeps the old teardown. Refcount at this+0x48 (this+18 DWORDs). |
Feature_3403109688 |
gate |
added (CFR gate) | CFR flag gating the double-check + compare-exchange teardown; the original unconditional s_pInstance=0 + destroy path still ships in .7623. |
Attack Path
TheWallet::Release nulls the singleton and frees it without re-checking for a concurrent re-reference, leaving a dangling pointer
Derived from the patch delta: the checks added by the vendor identify which fields crossed a trust boundary unvalidated. Reachability and privilege are taken from the call chain in the RCA report.