最近,我们的漏洞检测系统在 Solana 的 rBPF(即所有 Solana dApp 运行的虚拟机:https://github.com/solana-labs/rbpf)中发现了一个严重问题。经过仔细调查,我们发现这是一个整数溢出漏洞,可以被利用来使整个 Solana 网络崩溃。我们已将该漏洞报告给 Solana 安全团队,该团队立即着手确认和修复该漏洞。截至撰写本文时,几乎所有验证节点都已收到补丁并升级到最新版本,这意味着现在可以公开披露此信息。
eBPF 和 rBPF
扩展伯克利报文过滤器(eBPF[1])最初是为了在内核中过滤报文而开发的。由于 eBPF 的安全性、效率和可扩展性,它现在已广泛应用于网络、跟踪、分析等各个领域[2]。考虑到 eBPF 的强大功能,Solana 也选择它作为智能合约的执行引擎。要构建 Solana 上的 dApp,开发人员需要使用 Rust 开发智能合约,然后将其编译成 eBPF 字节码。
为了托管 Solana 的 dApp,需要一个精确的 eBPF 虚拟机。在这种情况下,Solana 使用了 rBPF,这是一个用 Rust 编写的 eBPF 虚拟机。然而,所提出的虚拟机(即 rBPF)是否健壮、安全和精确尚不确定。一旦 rBPF 中存在安全问题,所有包含 rBPF 的验证者都会受到影响,从而给整个 Solana 网络带来巨大损失(例如 DDoS 攻击)。
漏洞的根本原因
我们开发了一个用于定位 rBPF 漏洞的工具。该工具仍在积极开发中。在此过程中,我们在 rBPF(版本 0.2.16)中发现了一个严重问题,该问题可能导致整个网络瘫痪。
具体来说,文件“elf.rs”中的“load”函数用于解析和验证 ELF 文件(智能合约)。首先,“load”函数会读取 ELF 结构并调用“relocate”函数来设置被调用者偏移量。然而,在“relocate”函数中,属性“sym.st_value”直接从ELF 文件中检索。如果“st_value”足够大,在计算“addr”(即“sym.st_value”和“refd_pa”的总和)时可能会触发整数溢出。

在这种情况下,攻击者可以创建一个恶意的 ELF 文件作为智能合约,从而触发整数溢出。之后,每个验证者都会运行目标 ELF 文件,rBPF 会因“add with overflow”而崩溃。

此时,rBPF 会卡住,新的交易将无法执行,从而导致 DoS 攻击。正如以下所示,由于加载 ELF 文件时的整数溢出,我们可以观察到节点卡在“Finalizing transaction”状态。

此问题是在 https://github.com/solana-labs/rbpf/pull/200 中引入的,这意味着 rBPF 从 0.2.14 版本开始就存在此漏洞。我们在 2021 年 12 月 6 日发现了该问题并报告给了 Solana 安全团队。Solana 在收到我们的报告后,通过使用 safemath 机制在几个小时内修复了该问题。修复代码位于 https://github.com/solana-labs/rbpf/pull/236。截至撰写本文时(2021/12/30),已有超过 86% 的验证者已升级到最新版本。
[1] https://en.wikipedia.org/wiki/Berkeley_Packet_Filter
[2] https://ebpf.io/
时间线
- 2021/12/06:问题报告给 Solana 安全团队
- 2021/12/06:漏洞被修复
- 2021/12/30:该漏洞信息被发布
- 2022/01/28:分配 CVE-2021–46102



