KeyFrame內部研究專用

How to diagnose a faulty compiler: the LLVM bug | DSS Monthly Webinar (September 23rd)

DeFi Security Summit - DSS·9月24日週二·65 min英文

三句話摘要

Aave 協議在 zkSync 部署時發現的 LLVM 編譯器最佳化器漏洞:魔術常數架構不匹配導致用戶配置位清除錯誤。 在跨架構編譯場景中,不能假設任何工具(包括業界标准編譯器)的正確性,必須在實際目標虛擬機上進行端到端測試和模糊測試。 防線的失效層級:儘管部署前做了充分測試(單元測試、集成測試、正式驗證、代碼審查),編譯器層的 bug 仍然繞過所有防線,說明需要不信任編譯器正確性的假設,特別是跨架構時。

重點整理

重點
  • 1

    防線的失效層級:儘管部署前做了充分測試(單元測試、集成測試、正式驗證、代碼審查),編譯器層的 bug 仍然繞過所有防線,說明需要不信任編譯器正確性的假設,特別是跨架構時。

  • 2

    最佳化的隱藏風險:LLVM 為減小代碼大小而做的旋轉左移最佳化邏輯本身正確,但應用到非預期的位寬架構(256 位而非 64 位)時,魔術常數值導致完全不同的語義行為——旋轉出大量 0 位而非預期的 1 位。

  • 3

    跨鏈部署的脆弱性:同樣代碼在以太坊等其他網路完美運行,卻在 zkSync 異常,證明問題出在編譯鏈中針對 zkSync 的部分,而非應用邏輯,強調了對新環境底層工具的謹慎態度。

實用技巧與重點

乾貨
  • 編譯流程:Solidity → Solc → UEL → zkSol → LLVM → ZK EVM bytecode
  • 問題函數:`setUserBorrowAsCollateral()`,管理 256 位的 user configuration map,每個儲備用 2 位表示(1 bit 借用標誌 + 1 bit 抵押品標誌)
  • LLVM 最佳化
  • 原邏輯:左移 1 到目標位置 → 按位取反 → 按位與
  • 最佳化後:預先計算按位取反結果作為魔術常數 → 用 rotate-left 把常數的 0 位旋轉到目標位置
  • 魔術常數值
  • 設計值(64 位):0xFFFFFFFFFFFFFFFE(63 個 1 後跟 1 個 0)
  • 實際值(256 位):0x00...00FFFFFFFFFFFFFFFE(左側隱式補 192 個 0)
  • Rotate-left 行為對比
  • 64 位預期:旋轉出 63 個 1,把 1 個 0 旋轉到底部 ✓
  • 256 位實際:旋轉出 63 個 1 和 192 個 0,把這批 0 旋轉到底部 ✗
  • 影響:索引 3 的借用位清除時,索引 0、1、2 的所有位都被清除
  • 漏洞發現工具與方法
  • 最小化測試合約隔離問題
  • 編譯並查看 ZK EVM 汇編代碼
  • grep 搜尋 `shl` 和 `roll` 指令
  • 模式比對發現異常常數
  • LLVM 修復:改用 `GetSignConstant()` 為架構生成正確填充的常數(已上游合併,修復於上月)
  • 測試工具集:Foundry Suite、Cur Properties Suite、自定義差異監控、正式驗證(EVM 層)、模糊測試

結論

結論

在跨架構編譯場景中,不能假設任何工具(包括業界标准編譯器)的正確性,必須在實際目標虛擬機上進行端到端測試和模糊測試。

完整解析

詳細

Aave 協議是跨鏈借貸平台,為了在 zkSync 這個新的 Layer 2 方案上部署,需要通過 zkSync 自有的虛擬機 ZK EVM 編譯相同的 Solidity 代碼。在激活前,團隊進行了全面測試:單元測試全數通過、集成測試模擬真實場景、代碼審查確認邏輯完全一致、參數配置標準無異常。激活時的治理提案在五天投票期內順利通過,看起來是個常規流程。

但激活後不久,負責用户界面測試的團隊發現了異常現象:執行特定組合操作時,系統表現出完全違反協議邏輯的行為——用户提供兩種抵押品、借入兩種資產、只偿还其中一种的部分金額後,系統竟允許其提取所有抵押品而借款仍未結清。在沒有公開披露的情況下,團隊立即暫停了該資金池。

根本原因搜尋從排除假設開始。由於同樣代碼在以太坊等其他網路表現正常,且部署前驗證了代碼與已上線的其他實例完全一致,問題絕非應用邏輯缺陷。團隊系統地排除了配置問題、輔助合約問題,最終將異常隔離到 `setUserBorrowAsCollateral()` 函數——這個管理用户配置位向量的核心函數。

Sor 的安全研究員應邀深入編譯器層面調查。他們採用了高效的隔離策略:創建一個最小化測試合約,只包含問題函數,編譯後生成簡潔的汇編代碼。在這段短小的汇編中,他們發現了可疑的 `roll`(旋轉左移)指令配合一個看似隨意的魔術常數 0xFFFFFFFFFFFFFFFE。

問題的關鍵在於 LLVM 的編譯器優化策略。為了減小智能合約的部署成本(代碼越小 gas 費越低),LLVM 將原本的三步操作——左移 1、按位取反、按位與——優化成一步:預先將按位取反應用於常數,再用旋轉左移把常數中的 0 位旋轉到目標位置。這個優化在 64 位架構上完美無缺。但 zkSync 的 EVM 使用 256 位字。當 LLVM 接收到這個為 64 位設計的常數時,會自動在左側補充 192 個零位。結果是旋轉操作將這批零位也旋轉了出來,清除比預期更多的位——所有索引小於目標儲備的借用和抵押位都被意外清零。

這個事件最值得反思的地方在於防線層級的失效。正式驗證方法針對 EVM 代碼有效,但未涵蓋 ZK EVM。LLVM 本身是生產級編譯器,被 Rust 等頂級項目廣泛使用。代碼部署前的所有測試都未發現異常。然而,編譯鏈中的架構特性不匹配——64 位常數應用於 256 位運算——造成了漏洞。問題已在 LLVM 上游修複,團隊改用架構感知的常數生成函數。zkSync 隨後更新了編譯器版本,Aave 最終成功激活。

關鍵時刻

Pipeline v2

帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。

事實查核

Pipeline v2

說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。

更多「Web3 安全」的內容

IF YOU OWN XRP YOU NEED TO SEE THIS PRICE MANIPULATION! ⚠️
8 min
Web3 安全英文8月14日

IF YOU OWN XRP YOU NEED TO SEE THIS PRICE MANIPULATION! ⚠️

Zach Humphries

  • 機構支撐的積極意義:價格操縱常被視為負面,但Ripple掌握大量XRP供應與escrow,在熊市期間提高價格下限,實際上替零售投資者鎖定了低風險的積累區間,這不是剝削而是市場穩定機制。
  • 歷史模式驗證:2024年7月至11月XRP在50美分附近橫盤整理,低點觸及42美分(wick),高點65美分;隨後11月5日至12月5日單月上漲456%,年底到2025年初累計漲幅534%,這個歷史周期正在1美元價位重演。
  • 比特幣聯動邏輯:講者在4-5月就預測「如果比特幣跌至60k以下,XRP會跌至1美元或更低」,此預測精準應驗,反映出熊市中兩者的明確連動關係。
Minimmit, Multimmit and the New Consensus Frontier with Patrick O'Grady
72 min
Web3 安全英文PODCAST8月5日

Minimmit, Multimmit and the New Consensus Frontier with Patrick O'Grady

Zero Knowledge

  • 反向 Linux 架構:Commonware 刻意暴露棧各層級控制,讓開發者自訂執行環境、共識機制、密碼學實現,而非像 Cosmos SDK 只允許應用層以上定制。2-3 個月能組裝一條定製鏈,代價是額外深度但回報是長期維護成本降低及效能優化彈性。
  • 容錯假設的典範轉移:Alpine Glow(Solana 2025)實現單輪投票定終的關鍵是將容錯預算分離為獨立的 Byzantine 和 Crash 容限。傳統系統把 33% 當一個整體預算;新模型允許 20% 惡意加 20% 崩潰,打破了 PBFT 理論界線,釋放單輪設計空間。
  • Minimet 與 Multimet 的遞進:Minimet 是 5F+1 設定下的乾淨構造,實現更短視圖延遲;Multimet(剛發布)進一步允許並行 mini-commits 且驗證者可推翻領導者審查,使用者交易在全球分布式網路達到 200-300 毫秒端到端定終。
Private Information Retrieval (PIR) with Alex Hoover
64 min
Web3 安全英文PODCAST7月29日

Private Information Retrieval (PIR) with Alex Hoover

Zero Knowledge

  • PIR 保護的是訪問模式,不是資料本身
  • PIR 與加密不同,它關注的是隱藏「客戶端查詢了什麼」,而非「資料是否加密」。在公開資料庫(如區塊鏈)上,客戶端可以在不洩露查詢對象給伺服器的情況下檢索特定條目,解決了輕量級客戶端的隱私和防審查問題。
  • 客戶端預處理方案是突破瓶頸的關鍵