Heap Buffer Overflow in FreeRDP persistent cache v2 parser FreeRDP
What fixes it
- 3.32.0FreeRDP, cGitHub
A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.
Description
Summary A heap‑buffer‑overflow vulnerability exists in FreeRDP’s persistent cache v2 parser. When processing a maliciously crafted persistent cache v2 file, integer wraparound within bitmap‑size calculation leads to inconsistent buffer‑size accounting, which can trigger heap memory corruption, denial‑of‑service and potential arbitrary code execution. Details This vulnerability resides in persistent_cache_read_entry_v2 inside libfreerdp/cache/persistent.c. The helper function persist_cache_get_data computes bitmap data size with the expression 4ull * entry->width * entry->height. When parsing a malicious v2 persistent cache file, attacker‑controlled large width and height values trigger 64‑bit unsigned integer wraparound, producing a small falsified expected value. The existing check if (expected > UINT32_MAX) cannot reject this wrapped small value. allocated = MAX(0x4000, expected) guarantees the heap buffer allocated via winpr_aligned_recalloc is at least 0x4000 bytes. However, entry->size is assigned the wrapped‑around small expected value. In persistent_cache_read_entry_v2, the code performs:
if (fread(entry->data, 0x4000, 1, persistent->fp) != 1) return -1; It unconditionally reads fixed 0x4000 (16 KiB) bytes from the cache file into entry->data. Although the heap buffer itself is sized for 0x4000, the variable entry->size holds the wraparound‑truncated small value. This inconsistent size accounting introduces risks for subsequent logic that relies on entry->size. Additionally, the helper scan‑loop function persistent_cache_read_v2 uses hard‑coded fseek(fp, 0x4000, SEEK_CUR) to skip bitmap payload. Combined with the wraparound‑corrupted dimension values, file‑pointer mis‑positioning occurs during cache‑file traversal, leading to parsing‑state corruption, out‑of‑bounds memory access when interpreting subsequent cache‑entry headers, and heap corruption. Relevant real upstream vulnerable snippet:
static int persistent_cache_read_entry_v2(rdpPersistentCache* persistent, PERSISTENT_CACHE_ENTRY* entry) { PERSISTENT_CACHE_ENTRY_V2 entry2 = WINPR_C_ARRAY_INIT;
WINPR_ASSERT(persistent); WINPR_ASSERT(entry);
if (fread(&entry2, sizeof(entry2), 1, persistent->fp) != 1) return -1;
entry->key64 = entry2.key64; entry->width = entry2.width; entry->height = entry2.height; entry->flags = entry2.flags;
if (!persist_cache_get_data(persistent, entry)) return -1;
if (fread(entry->data, 0x4000, 1, persistent->fp) != 1) return -1;
return 1; }
An attacker can construct a malicious v2 persistent cache file with oversized width and height fields to trigger this integer wraparound. The mismatch between actual allocated buffer capacity and entry->size, paired with hard‑coded 16‑KiB read / fseek operations, corrupts parsing state and triggers heap‑based out‑of‑bounds access. References: PoC repository: https://github.com/programmervuln/freerdp-persistent-cache-v2-heapoverflow Source file: [https://github.com/FreeRDP/FreeRDP/blob/master/libfreerdp/cache/persistent.c PoC Build FreeRDP 3.31.1 from source with ASAN (‑fsanitize=address) enabled to capture crash traces. Compile gen_poc_v2.c from the PoC repository to generate malicious persistent cache v2 file. Configure FreeRDP client to load this malicious cache file. Launch FreeRDP client to trigger persistent‑cache parsing logic. ASAN will report heap‑memory corruption crash inside the persistent‑cache parsing code path. Full ASAN crash backtrace can be provided upon maintainer request. Impact Vulnerability class: CWE‑122 Heap‑based Buffer Overflow Successful exploitation causes heap memory corruption, application denial‑of‑service, and theoretically potential arbitrary code execution within FreeRDP client process. Attack prerequisite: Local user interaction; victim must load a malicious persistent cache v2 file. Affected component: libfreerdp/cache/persistent.c, persistent cache v2 parser. Affected version: FreeRDP 3.31.1. No patched version available at time of reporting. CVSS 3.1:CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H (7.8 High)
Text from GitHub Advisory Database
Affected versions 1
- FreeRDP, c<= 3.31.1GitHub