Skip to content
Vol. 1 · Ed. 2026
CyberGlossary
Entry № 527

堆溢出

审核人Cybersecurity entrepreneur & security researcher

堆溢出 是什么?

堆溢出发生在动态分配内存中的缓冲区溢出,通常会破坏分配器元数据、函数指针或对象的虚函数表。


堆溢出会写入超出堆分配缓冲区末尾的数据,破坏相邻的内存块(chunk),或破坏由 malloc/free、jemalloc、mimalloc 等分配器管理的记账元数据。与栈溢出不同,这里没有可以直接劫持的返回地址;攻击者转而破坏程序稍后会信任的数据——相邻对象的函数指针、C++ 虚函数表指针、智能指针的控制块,或在 free() 期间使用的分配器空闲链表指针(即经典的 "unlink" 原语)。

由于堆的布局是非确定性的,利用过程依赖于堆布局操纵(heap grooming / feng shui):通过执行受控的分配与释放,使一个有用的目标恰好落在易受攻击缓冲区之后。一个经典的真实案例是 GHOSTCVE-2015-0235),这是 glibc 中 __nss_hostname_digits_dots() 函数里的一个堆溢出,可通过 gethostbyname() 触达;Qualys 于 2015 年演示了针对 Exim 邮件服务器的完整远程代码执行,而该缺陷自 glibc 2.2 起便悄然存在。CVE-2018-4407 在苹果的 XNU 内核中展现了同一类问题,只需一个精心构造的 TCP 数据包即可通过网络远程触发。

flowchart TD
  A[相邻分配受害对象 + 易受攻击缓冲区] --> B[堆布局操纵将目标置于缓冲区之后]
  B --> C[溢出写入超出缓冲区末尾]
  C --> D{被破坏的目标}
  D -->|分配器元数据| E[free unlink -> 任意写入]
  D -->|函数指针 / vtable| F[重定向控制流]
  E --> G[代码执行]
  F --> G

防御手段将分配器加固(元数据完整性检查、安全 unlink、内存块隔离、保护页)与 ASLRCFI、沙箱以及向 Rust 等内存安全语言的迁移结合起来。堆溢出在浏览器、内核和文档解析器的利用中仍占据核心地位,并频繁出现在 Pwn2Own 的获胜利用链中。

示例

  1. 01

    GHOST(CVE-2015-0235)——glibc 中 gethostbyname 的堆溢出,可通过 Exim 邮件服务器触达。

  2. 02

    CVE-2018-4407——XNU 内核 TCP 选项的堆溢出,可通过网络远程触发。

常见问题

堆溢出 是什么?

发生在动态分配内存中的缓冲区溢出,通常会破坏分配器元数据、函数指针或对象的虚函数表。 它属于网络安全的 漏洞 分类。

堆溢出 是什么意思?

发生在动态分配内存中的缓冲区溢出,通常会破坏分配器元数据、函数指针或对象的虚函数表。

如何防御 堆溢出?

针对 堆溢出 的防御通常结合技术控制与运营实践,详见上方完整定义。

堆溢出 还有哪些其他名称?

常见的别称包括: 堆缓冲区溢出。

相关术语

另见