返回博客

Solana 网络重大漏洞的发现与及时修复

Code Auditing
2022年6月7日
阅读约 5 分钟

在四月,我们的漏洞检测系统在 Solana 的 rBPF(即所有 Solana dApp 运行的虚拟机:https://github.com/solana-labs/rbpf)中发现了一个问题。经过仔细调查,我们发现这是一个安全漏洞,可能导致合约执行路径错误。我们已将此 bug 报告给 Solana 安全团队,该团队立即确认并修复了此漏洞。此外,他们还向我们的团队授予了价值 800,000 美元的 SoL 代币。

该漏洞存在于较新版本的 rBPF (0.2.26 至 0.2.27) 中。在我们报告问题时,主网上使用的验证器尚未升级到受影响的版本。我们的系统在受影响版本合并之前就检测到了该问题,使得主网的验证器免疫于此漏洞。

我们将在下文中详细阐述此漏洞的细节。

1. eBPF 和 rBPF

eBPF(扩展 Berkeley 数据包过滤器)最初是为了在内核中过滤数据包而开发的。由于 eBPF 的安全性、效率和可扩展性,它现在已被用于网络、跟踪、分析等各种领域,等等。考虑到 eBPF 丰富的功能,Solana 使用它作为智能合约的执行引擎。要构建 Solana 上的 dApp,开发人员使用 Rust 开发其智能合约,并将其编译为 eBPF 字节码。

Solana 使用 rBPF,一个用 Rust 编写的虚拟机,来执行编译后的 BPF 字节码。然而,是否提议的虚拟机(即 rBPF)健壮、安全且精确尚不清楚。如果 rBPF 内部存在安全问题,所有包含 rBPF 的验证器都可能受到影响,导致整个 Solana 网络遭受巨大损失(例如,资金损失)。

2. 根本原因

我们开发了一个工具,可以自动定位 rBPF 的实现错误并定期扫描 rBPF 的代码。在扫描过程中,我们在 rBPF (0.2.26 版本) 中发现了一个严重问题,这可能导致合约执行路径错误。

具体来说,sdiv 指令用作有符号除法指令,作为 rbpf 0.2.26 中默认启用的功能引入。sdiv 支持 32 位(即 sdiv32)和 64 位(sdiv64)操作数的除法。对于 sdiv32 指令,计算结果存储在 bpf 寄存器中,该寄存器为 64 位。然而,如果 sdiv32 指令之后的指令将计算结果读取为 64 位,结果可能会有所不同。这是因为 rBPF 在 JIT 编译过程中,并未将 sdiv32 的计算结果扩展为正确的 64 位值。

例如,如果一个正数(即 12)除以一个负数(即 -4)使用 sdiv32,在 32 位和 64 位下,正确结果都应该是 -3。下面的代码是一个示例。

在 JIT 和解释模式下运行并跟踪它之后,我们可以观察到它们之间的差异:

2.1 解释模式

0 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    29: lddw r5, 0x10000000c
 1 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 000000010000000C, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    31: sdiv32 r5, -4
 2 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, FFFFFFFFFFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    32: jslt r5, 0, lbb_7
 3 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, FFFFFFFFFFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    36: exit

2.2 JIT 模式

0 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    29: lddw r5, 0x10000000c
 1 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 000000010000000C, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    31: sdiv32 r5, -4
 2 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 00000000FFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    32: jslt r5, 0, lbb_7
 3 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 00000000FFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    33: lddw r0, 0x1
 4 [0000000000000001, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 00000000FFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    35: exit

在解释模式下,寄存器 r5 被设置为 0xFFFFFFFFFFFFFFFD(在 32 位和 64 位模式下均为 -3),而在 JIT 模式下,r5 被设置为 0x00000000FFFFFFFD。在这种情况下,对于接收 64 位值的 jslt 指令,r5 将被识别为正数(即 0x00000000FFFFFFFD)。之后,执行路径将完全错误。

3. 影响

这种错误的实现可能导致合约执行路径不正确,并可能引发严重问题。

例如,如果智能合约中的一个关键操作依赖于 sdiv32 指令的结果,可能会导致执行结果不正确,并被攻击者滥用。

该问题已在 https://github.com/solana-labs/rbpf/pull/283 中引入,这意味着 rBPF 从 0.2.26 版本起就存在漏洞。我们在 2022 年 4 月 28 日发现了问题并将其报告给了 Solana 安全团队。该团队迅速响应了我们的报告,并在几小时内通过为 sdiv32 指令添加符号扩展操作修复了该问题。修复提交于 https://github.com/solana-labs/rbpf/pull/310。由于我们团队的及时发现和报告,主网的验证器并未受到此漏洞的影响。

此问题被归类为协议活性 bug,因此 Solana 授予了 800,000 美元的 bug 奖励。

时间线

  • 2022/04/28:我们将问题报告给了 Solana 安全团队
  • 2022/04/29:漏洞已修复
  • 2022/05/09:分配了 CVE-2022-23066
  • 2022/06/01:授予了 bug 奖励

关于 BlockSec

BlockSec 团队专注于区块链生态系统的安全,并与领先的 DeFi 项目合作,以保障其产品安全。该团队由来自学术界和工业界的顶尖安全研究人员和经验丰富的专家创立。他们已在著名会议上发表了多篇区块链安全论文,报告了多个 DeFi 应用的零日攻击,并发布了高影响力安全事件的详细分析报告。

Twitter: [BlockSecTeam]

Medium: https://blocksecteam.medium.com

网站: https://www.blocksec.com

订阅最新动态
Bitget 3.875亿美元链下漏洞事件:不止于密钥与合约
Security Insights

Bitget 3.875亿美元链下漏洞事件:不止于密钥与合约

2026年9月24日,攻击者利用第三方安全产品漏洞,获取内部凭证并伪造提现指令,导致Bitget部分运营钱包资金转出约3.875亿美元,涉及以太坊、其他EVM网络、XRP Ledger、Zcash和TRON,私钥及冷钱包未受影响。本文梳理事件路径与资金流向,分析资产快速转换及生态恢复应对,提出机构纵深防御体系,并说明授权区块链渗透测试如何验证跨层安全假设。

损失约1130万美元:Multicall Router、Nostra | BlockSec Weekly
Security Insights

损失约1130万美元:Multicall Router、Nostra | BlockSec Weekly

本报告覆盖2026/09/14至09/20,分析以太坊与Starknet上两起共约1130万美元损失的安全事件。较大一起中,多重调用路由器将自身地址当作调度目标,致嵌套调用以路由器已授权身份而非外部调用者身份进入Safe钱包的Gateway模块,约2900个aEthrsETH被转入攻击者创建的Uniswap v4池。Starknet上,Nostra预言机仅需一个聚合来源,三个价格源中仅两个参与聚合时,被操纵的浅池报价与正常报价平均,使NSTR估值约49.52美元,支持约350万美元超额抵押借贷。

~3.2亿美元损失:Liquid Network、Symbiosis 遭利用攻击 | BlockSec
Security Insights

~3.2亿美元损失:Liquid Network、Symbiosis 遭利用攻击 | BlockSec

本报告覆盖2026/09/07-09/13,分析两起共损失约3.2亿美元的安全事件,含此前未覆盖的Liquid Network于09/06遭利用事件。较大事件中,Elements的rangeproof验证缓存因字段拼接无分隔符导致验证结果错配,攻击者伪造4000枚无支撑L-BTC并几乎全部兑出。Symbiosis跨链桥比特币路线因手续费未做负值校验,330聪存款铸造出46,116,860,184.27388234 syBTC,流动性池仅存11.26 syBTC,致约970万美元损失(约9.97 BTC)。

Web3 最佳安全审计方

在上线之前验证设计、代码与业务逻辑,对标业内最高安全标准。

BlockSec 审计