Solana 网络中的一个关键漏洞是如何被发现并及时修补的

Solana 漏洞:rBPF 错误影响合约执行路径

Solana 网络中的一个关键漏洞是如何被发现并及时修补的

在四月,我们的漏洞检测系统在 Solana 的 rBPF(即所有 Solana dApp 运行的虚拟机:https://github.com/solana-labs/rbpf)中发现了一个问题。经过仔细调查,我们发现这是一个安全漏洞,可能导致合约执行路径错误。我们已将此 bug 报告给 Solana 安全团队,他们立即确认并修复了该漏洞。此外,他们还授予了我们的团队价值 80 万美元的 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 的实现 bug 并定期扫描 rBPF 的代码。在扫描过程中,我们在 rBPF(版本 0.2.26)中发现了一个严重问题,这可能导致合约的执行路径错误。

具体来说,sdiv 指令被用作有符号除法指令,作为 rbpf 0.2.26 中默认启用的功能引入。sdiv 支持 32 位(即 sdiv32)和 64 位(sdiv64)操作数的除法。对于 sdiv32 指令,计算结果存储在 64 位 bpf 寄存器中。然而,如果 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。在这种情况下,r5 对于接收 64 位值的 jslt 指令将被识别为一个正数(即 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 授予了 80 万美元的 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

Sign up for the latest updates