Back to Blog

Solana 網路重大漏洞的發現與即時修復過程

Code Auditing
June 7, 2022
6 min read

四月,我們的漏洞檢測系統在 Solana 的 rBPF(即所有 Solana 去中心化應用運行的虛擬機:https://github.com/solana-labs/rbpf)中發現了一個問題。經過仔細調查,我們發現這是一個可能導致合約執行路徑錯誤的安全漏洞。我們已向 Solana 安全團隊報告了該錯誤,團隊立即確認並修復了此漏洞。此外,他們還授予我們團隊價值 80,000 美元的 SoL 代幣獎勵。

該漏洞存在於較新版本的 rBPF(0.2.26 至 0.2.27)中。在我們報告該問題時,主網上使用的驗證器尚未升級到受影響的版本。我們的系統在受影響的版本合併之前就檢測到了該問題,這使得主網的驗證器免受此漏洞的影響。

我們在下文中詳細闡述了此漏洞的細節。

1. eBPF 與 rBPF

eBPF(擴展柏克萊封包過濾器)最初是為在核心(kernel)中過濾封包而開發的。由於 eBPF 的安全性、效率和可擴展性,它現在被廣泛應用於網路、追蹤、剖析 多個領域。考慮到 eBPF 強大的功能,Solana 將其用作智慧合約的執行引擎。為了在 Solana 上構建去中心化應用,開發人員使用 Rust 開發智慧合約,並將合約編譯為 eBPF 位元組碼。

Solana 使用 rBPF(一個用 Rust 編寫的虛擬機)來執行編譯後的 BPF 位元組碼。然而,該虛擬機(即 rBPF)是否強大、安全且精確尚不可知。如果 rBPF 內部存在安全問題,所有包含 rBPF 的驗證器都可能受到影響,從而導致整個 Solana 網路的巨大損失(例如,資金損失)。

2. 根本原因

我們開發了一種工具,可以自動定位 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 和直譯(Interpreted)兩種模式下運行並追蹤後,我們觀察到了它們之間的差異:

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 指令增加符號擴展(sign-extend)操作,在數小時內修復了該問題。該修復位於 https://github.com/solana-labs/rbpf/pull/310。由於我們團隊的及時檢測與報告,主網的驗證器並未受到此漏洞的影響。

此問題被歸類為協議活躍度(protocol liveness)錯誤,並獲得了 Solana 頒發的 80,000 美元漏洞獎勵。

時間軸

  • 2022/04/28:我們向 Solana 安全團隊報告了該問題
  • 2022/04/29:漏洞已修復
  • 2022/05/09:分配了 CVE-2022-23066 編號
  • 2022/06/01:獲得漏洞獎勵

關於 BlockSec

BlockSec 團隊致力於區塊鏈生態系統的安全,並與領先的 DeFi 專案合作以保護其產品。該團隊由來自學術界和工業界的頂尖安全研究人員和經驗豐富的專家組成。他們在著名的會議上發表了多篇區塊鏈安全論文,報告了多起 DeFi 應用程式的零時差攻擊(Zero-day attack),並發布了關於高影響力安全事件的詳細分析報告。

推特:[BlockSecTeam]

Medium:https://blocksecteam.medium.com

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

Sign up for the latest updates
電子報 - 2026年6月
Security Insights

電子報 - 2026年6月

本月報告涵蓋2026年6月三起最大安全事件,確認損失合計約2200萬美元。一次精密蜜罐攻擊利用未受檢查的代幣授權,從JaredFromSubway的MEV機器人抽走約1500萬美元。兩個舊版Aztec rollup部署因證明結算邊界漏洞損失約435萬美元。SecondFi的Ed25519實現缺陷暴露錢包私鑰,導致374個錢包共損失約240萬美元。三起事件共同模式:表面完整但從未真正執行的安全保證。

~$400萬損失:Taiko、SecondFi遭攻擊 | BlockSec週報
Security Insights

~$400萬損失:Taiko、SecondFi遭攻擊 | BlockSec週報

本週區塊鏈安全報告涵蓋2026年6月22-28日兩起重大事件,以太坊和Cardano確認損失約410萬美元。Taiko橋接漏洞結合了外洩的SGX飛地簽名密鑰與不完整的認證策略,未能拒絕調試飛地,使攻擊者註冊惡意證明者並偽造L2狀態證明。SecondFi錢包漏洞源於Ed25519隨機數派生中的密碼學實現缺陷,移除了秘密輸入,可從Cardano公開交易數據離線恢復私鑰。

~$18M損失:jaredFromSubway、Aztec及更多 | BlockSec每週快報
Security Insights

~$18M損失:jaredFromSubway、Aztec及更多 | BlockSec每週快報

本週區塊鏈安全報告涵蓋2026年6月15日至21日,以太坊與BNB Chain共發生3起重大事件,總損失約1830萬美元。重點分析兩起事件:jaredFromSubway事件揭示反向授權攻擊模式——MEV機器人主動將資產授權給不可信第三方合約套利,攻擊者構造假包裝代幣與交易池,發出真實事件但從未消耗授權額度,損失約1500萬美元。Aztec三日內第二次漏洞:逃生艙ZK電路中`old_data_root`兩個見證值缺少相等約束,致使攻擊者可用偽造Merkle樹證明虛假票據所有權並通過鏈上驗證。

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit