ANT-2026-HN9XZXJ9 · freerdp
heap-buffer-overflow medium
GHSA-mpxh-8fq3-x8mh GHSA-mvpx-xj7r-3p3r GHSA-p6r2-4hgm-m6ff
Severity Claude critical · Security research firm medium · Maintainer unknown
Discovered by Claude Mythos Preview
Anthropic's analysis, sealed at approval. Disclosure to the maintainer was performed by Trail of Bits.
ANT-2026-HN9XZXJ9: heap-buffer-overflow write (attacker-controlled offset, partially-controlled data via rle delta values; up to ~15kb overwrite past ptempdata with these parameters, further with larger nxdst) in planar.c:472
In FreeRDP's planar bitmap codec (libfreerdp/codec/planar.c), the X-axis bounds check at line 968 validates nXDst against the caller's destination stride (nDstStep) rather than the internal temp buffer stride (nTempStep) when the temp-buffer path is active. A malicious RDP server can send RDPGFX planar data with a large nXDst (e.g. 6000) that passes the check (24016 <= 28032) but causes planar_decompress_plane_rle to write up to offset ~40131 into a 24576-byte pTempData allocation. The attacker controls the destination offset and RLE-decoded byte content, yielding an out-of-bounds heap write in the connecting FreeRDP client.
Target
Project: freerdp
Location: planar.c:472
Technical Details
ASAN: heap-buffer-overflow WRITE of size 1 at 0x52b0000062e2, 170 bytes past the end of a 24632-byte heap region. The bounds check at planar.c:968 compares against nDstStep (28032) instead of nTempStep (256), so when the temp-buffer code path is used the check does not actually constrain writes to pTempData. Large attacker-supplied nXDst values therefore pass validation and drive OOB writes during RLE plane decompression.
Crash trace (truncated — full trace in attached crash.log):
The PoC is a C harness (`planar_poc_gfx.c`, 6225 bytes) that demonstrates a heap-buffer-overflow WRITE vulnerability in FreeRDP's planar codec (`libfreerdp/codec/planar.c`).
**Root Cause**: The X-axis bounds check at `planar.c:968` compares against `nDstStep` (the caller's destination stride of 28032) instead of `nTempStep` (the internal temp buffer stride of 256) when the temp buffer code path is active. This allows writing far past the end of `pTempData` (24576 bytes) when `nXDst` is large.
**Reproduction**: The harness simulates a malicious RDPGFX server scenario:
1. Creates a planar context sized 64x64 (pTempData = 24576 bytes, nTempStep = 256)
2. Calls `freerdp_bitmap_decompress_planar()` with nXDst=6000, which passes the buggy bounds check (24016 <= 28032) but results in writes up to offset 40131 in the 24576-byte temp buffer
**All 3 runs in a fresh container produced identical results**:
- ERROR: AddressSanitizer: heap-buffer-overflow on address 0x52b0000062e2
- WRITE of size 1 at `planar_decompress_plane_rle` (planar.c:472)
- Called from `freerdp_bitmap_decompress_planar` (planar.c:977)
- 170 bytes past end of 24632-byte heap allocation
- Exit code: 1
The vulnerability is exploitable in a realistic attack scenario where a malicious RDP server sends crafted RDPGFX planar data to a FreeRDP client.
Reproduction
- Server negotiates RDPGFX and sends planar-encoded bitmap data
- Planar context is initialized small (e.g. 64x64), allocating a ~24KB pTempData buffer with nTempStep=256
- Server supplies a large nXDst (e.g. 6000) alongside a large caller nDstStep (e.g. 28032)
- Bounds check at planar.c:968 compares 4*nXDst+16 against nDstStep instead of nTempStep and passes
- planar_decompress_plane_rle writes RLE-decoded bytes into pTempData at offsets up to ~40131, overflowing the 24576-byte buffer
[No reproducer or sanitizer output attached — request from cvd@anthropic.com if needed.]
Acknowledgement
This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-HN9XZXJ9.
Reference: ANT-2026-HN9XZXJ9
Anthropic CVD Policy: https://anthropic.com/security/cvd-policy
Triage and disclosure were performed by Trail of Bits.
- Verdict
- true positive
- Severity
- medium
Dates from discovery through public reveal.
- 2026-03-24 Reported to tracker
- 2026-04-30 Sent to maintainer
- 2026-04-30 Maintainer acknowledged
- 2026-05-13 Patch released
- 2026-05-20 Publicly revealed
SHA-3-512 hash:
29af186542c112b5343a65f02c7172778fb1557257c7f93bae53f138452377c80bff2e5179a0fdc789f462a28ae262e222512a5257acc425172a7f894d2c5468
Committed 2026-04-30 00:03 PT
Revealed 2026-05-20 00:40 PT
Verify (download preimage.json)
Show preimage JSON
{
"ant_id": "ANT-2026-HN9XZXJ9",
"bug_class": "heap",
"claude_severity": "critical",
"commit_sha": null,
"created_at": "2026-03-24T20:43:50+00:00",
"description": "In FreeRDP's planar bitmap codec (libfreerdp/codec/planar.c), the X-axis bounds check at line 968 validates nXDst against the caller's destination stride (nDstStep) rather than the internal temp buffer stride (nTempStep) when the temp-buffer path is active. A malicious RDP server can send RDPGFX planar data with a large nXDst (e.g. 6000) that passes the check (24016 <= 28032) but causes planar_decompress_plane_rle to write up to offset ~40131 into a 24576-byte pTempData allocation. The attacker controls the destination offset and RLE-decoded byte content, yielding an out-of-bounds heap write in the connecting FreeRDP client.",
"discovered_at": null,
"location": "planar.c:472",
"poc_sha256": null,
"preimage_version": 1,
"project": "freerdp",
"reproduction": [
"1. Server negotiates RDPGFX and sends planar-encoded bitmap data",
"2. Planar context is initialized small (e.g. 64x64), allocating a ~24KB pTempData buffer with nTempStep=256",
"3. Server supplies a large nXDst (e.g. 6000) alongside a large caller nDstStep (e.g. 28032)",
"4. Bounds check at planar.c:968 compares 4*nXDst+16 against nDstStep instead of nTempStep and passes",
"5. planar_decompress_plane_rle writes RLE-decoded bytes into pTempData at offsets up to ~40131, overflowing the 24576-byte buffer"
],
"technical_details": "ASAN: heap-buffer-overflow WRITE of size 1 at 0x52b0000062e2, 170 bytes past the end of a 24632-byte heap region. The bounds check at planar.c:968 compares against nDstStep (28032) instead of nTempStep (256), so when the temp-buffer code path is used the check does not actually constrain writes to pTempData. Large attacker-supplied nXDst values therefore pass validation and drive OOB writes during RLE plane decompression.",
"title": "heap-buffer-overflow write (attacker-controlled offset, partially-controlled data via rle delta values; up to ~15kb overwrite past ptempdata with these parameters, further with larger nxdst) in planar.c:472",
"vendor_severity": "medium"
}