FreeRDP堆缓冲区溢出漏洞CVE-2026-40033
FreeRDP 是一个免费、开源、跨平台的 RDP(Windows 远程桌面协议)实现,其主要用于Linux/macOS 远程管理 Windows 服务器。
一、基本情况
FreeRDP 是一款让 Linux、macOS 等系统能免费连接Windows远程桌面的工具库与客户端,可以替代商业远程桌面工具,节省成本。

FreeRDP 的核心作用是非 Windows 系统访问 Windows 远程桌面,替代 Windows 自带的 mstsc 工具,提供库(API)支持二次开发。
栋科技漏洞库关注到 FreeRDP 3.26.0 之前的版本中存在的堆缓冲区溢出漏洞,现已被追踪为CVE-2026-40033,CVSS 4.0评分为8.6。
二、漏洞分析
CVE-2026-40033是 FreeRDP 相关版本在 gdi_CacheToSurface 函数的堆缓冲区溢出漏洞,可能导致远程代码执行或客户端程序崩溃。
具体来说,该安全漏洞是 FreeRDP 客户端在处理 RDPGFX 图像缓存时的边界检查缺陷,远程攻击者可利用漏洞实现堆内存越界写入。
该安全漏洞成因是代码对矩形坐标做了最大值截断(上限为 16 位无符号整数最大值),但拷贝数据时却使用未经过截断的缓存项尺寸。
恶意RDP服务器发送构造的 RDPGFX 协议数据单元,通过绕过截断矩形校验实现 FreeRDP RDPGFX CacheToSurface 堆缓冲区溢出。
1、漏洞位置
该漏洞位于 gdi_CacheToSurface 函数中:程序对目标矩形进行校验时会将坐标截断至 UINT16_MAX(16 位无符号整数最大值),
但实际执行数据拷贝时却使用原始缓存项的宽 / 高尺寸。这会导致大规模堆内存越界写入,可能造成客户端崩溃或远程代码执行。
该漏洞可被恶意 RDP 服务器利用,但仅在客户端启用了 RDPGFX 功能时生效。
C 语言概念验证代码仅为本地测试工具,调用的逻辑与服务器发送 RDPGFX 数据触发的客户端处理逻辑完全一致。
2、详细说明
gdi_CreateSurface 函数会将表面尺寸按 16 字节对齐,
surface->width = gfx_align_scanline (createSurface->width, 16),surface->height = gfx_align_scanline (createSurface->height, 16)。
因此,若服务器指定创建表面尺寸为宽 65535、高 1,实际分配的表面大小为 65536×16 像素。
gdi_CacheToSurface 函数使用截断后的右 / 下边界构建 RECTANGLE_16 矩形。
由于矩形右边界被截断至 UINT16_MAX,即便实际拷贝的宽 / 高超出表面范围,矩形校验仍可能通过。
具体崩溃触发参数(攻击者可通过标准 RDPGFX 消息控制):
创建表面,指定宽 65535、高 1;
创建缓存项,指定宽 65535、高 1;
发送 CacheToSurface 指令,目标坐标为 x=65534,y=15。
三、POC概念验证
(一)本复现程序无需搭建真实的 RDP 服务器。
它模拟了 gdi_CacheToSurface 所使用的完整边界校验逻辑,随后使用与该函数完全一致的参数调用 freerdp_image_copy_no_overlap。
已在 Linux 系统上针对 FreeRDP 提交版本 23b36cd00ebf0ccd97750fcdbc9aa2f362352da7 完成测试。
1、使用地址消毒器(ASAN)/ 未定义行为消毒器(UBSAN)编译 FreeRDP(禁用本 PoC 不需要的可选依赖项):
管理员已设置登录后刷新可查看2、将此代码保存为 **poc_505.c**(例如保存至 /tmp/poc_505.c):
管理员已设置登录后刷新可查看3、编译并运行:
cd /tmp/freerdp-src/build-asan
gcc -g -O1 -fsanitize=address,undefined \
-I../include -I./include -I../winpr/include -I./winpr/include \
/tmp/poc_505.c \
-L./libfreerdp -L./winpr/libwinpr -lfreerdp3 -lwinpr3 \
-Wl,-rpath,./libfreerdp:./winpr/libwinpr -o /tmp/poc_505
ASAN_OPTIONS='detect_leaks=0:abort_on_error=1:halt_on_error=1:print_stacktrace=1' \
LD_LIpARY_PATH=./libfreerdp:./winpr/libwinpr \
/tmp/poc_505
预期结果:地址消毒器(ASAN)会报告大小为 262140 字节的**堆缓冲区溢出写入**。
(二)建议修复方案
在调用 `freerdp_image_copy_no_overlap` 之前,基于真实的(未被截断的)拷贝尺寸添加边界校验。
diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c
index feec35967..aaad7b349 100644
--- a/libfreerdp/gdi/gfx.c
+++ b/libfreerdp/gdi/gfx.c
@@ -1659,6 +1659,11 @@ static UINT gdi_CacheToSurface(RdpgfxClientContext* context,
if (!is_rect_valid(&rect, surface->width, surface->height))
goto fail;
+
+ if ((UINT32)destPt->x + cacheEntry->width > surface->width)
+ goto fail;
+ if ((UINT32)destPt->y + cacheEntry->height > surface->height)
+ goto fail;
if (!freerdp_image_copy_no_overlap(surface->data, surface->format, surface->scanline,
destPt->x, destPt->y, cacheEntry->width,
cacheEntry->height, cacheEntry->data, cacheEntry->format,
(三)影响范围
该漏洞为 FreeRDP 客户端的堆缓冲区溢出写入漏洞,所有使用 FreeRDP(如 xfreerdp)连接至攻击者控制、
且协商启用 RDPGFX 协议的 RDP 服务器的用户及应用程序均会受到影响。
攻击者最低可实现 FreeRDP 客户端远程崩溃(拒绝服务攻击),在此场景下危害程度较低;
由于攻击者可控制大规模堆内存越界写入(数据大小与内容均来自服务器控制的缓存像素数据),可能在客户端进程中执行任意代码。
攻击者可精准控制传入 gdi_CacheToSurface 函数的所有字段,且该漏洞存在于真实的服务器到客户端消息传输路径中。
(四)漏洞背景
该漏洞是 Anthropic 公司利用大语言模型进行开源软件自动化漏洞挖掘研究过程中发现的。
随后 Anthropic 委托 Trail of Bits 公司对该漏洞进行独立分类与验证。
四、影响范围
FreeRDP ≤ 3.25.0
五、修复建议
FreeRDP ≥ 3.26.0
六、参考链接
https://github.com/FreeRDP/FreeRDP/security/advisories/GHSA-p6r2-4hgm-m6ff