1. 引言
前序博客有:
- Polygon zkEVM Hexens审计报告解读
- Polygon zkEVM Spearbit审计报告解读(2022年12月版本)
- Polygon zkEVM Spearbit审计报告解读(2023年1月版本)
- Polygon zkEVM Spearbit审计报告解读(2023年3月版本)
- Polygon zkEVM ROM Spearbit审计报告解读(2023年6月Dragon Fruit升级版本)
主要内容见:
- Polygon zkEVM Security Review: Calldata bugfix review
审计内容见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/pull/23
本轮审计历时2天,共发现6个问题,其中低危漏洞1个,信息提示类5个。
在本审计报告中,风险分级为:
风险级别 | 影响:高 | 影响:中等 | 影响:低 |
---|---|---|---|
可能性:高 | 致命 | 高 | 中等 |
可能性:中等 | 高 | 中等 | 低 |
可能性:低 | 中等 | 低 | 低 |
其中:
- 1)影响:
- 高:会导致丢失协议中 > 10 % >10\% >10%资产,或对大多数用户有重大危害。
- 中等:丢失 < 10 % <10\% <10%资产,或仅丢失一部分用户的资产,但仍不可接受。
- 低:丢失很烦人但可接收。适用于可以很容易修复的网格攻击,甚至是gas不足。
- 2)概率:
- 高:几乎确定会发生,易于操作,或不易于操作但激励诱人。
- 中等:仅有可行性可能或动机,但相对有可能发生。
- 低:需要stars to align,或者几乎没有动机。
- 3)风险级别:
- 致命:(若已部署)必须尽快修复。
- 高:(若未部署),需在部署前修复。
- 中等:应该修复。
- 低:可修复。
2. 低危漏洞
2.1 低危漏洞1:CREATE2在存储calldata指针之后设置txCalldataLen
上下文见:
- zkevm-rom: create-terminate-context.zkasm#L746-L748
CALL* 系列opcodes和CREATE具有共同的模式:
- 先设置txCalldataLen为argsLengthCall参数
- 然后调用saveCalldataPointer。
而CREATE2中的这2个动作是相反的,其不会影响helper输出,但基于一致性考虑,应与其他opcodes保持相同的顺序。
建议:
- 先设置txCalldataLen,再调用saveCalldataPointer。
修复PR见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/pull/23
3. 信息类提示
3.1 信息类提示1:常量命名混乱
上下文见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/blob/4339357ee536333f8c8cfcbee1a0aa7fd43cae3d/main/constants.zkasm#L13
%CALLDATA_CTX常量名混乱,因同时还有calldataCTX变量。
建议:
- 将%CALLDATA_CTX常量,重命名为%CALLDATA_RESERVED_CTX。
修复PR见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/pull/23
3.2 信息类提示2:
上下文见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/blob/4339357ee536333f8c8cfcbee1a0aa7fd43cae3d/main/opcodes/calldata-returndata-code.zkasm#L27
- https://github.com/0xPolygonHermez/zkevm-rom-internal/blob/4339357ee536333f8c8cfcbee1a0aa7fd43cae3d/main/opcodes/calldata-returndata-code.zkasm#L134
- https://github.com/0xPolygonHermez/zkevm-rom-internal/blob/4339357ee536333f8c8cfcbee1a0aa7fd43cae3d/main/opcodes/calldata-returndata-code.zkasm#L161
注释中声称readFromCalldataOffset helper的输出变量为readFromCalldataOffset,但实际为readXFromCalldataResult。
A :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataOffset: result value]
建议:
- 修改注释中的输出为readXFromCalldataResult。
修复PR见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/pull/23
3.3 信息类提示3:无需在readFromCalldataOffset helper中保存D寄存器
上下文见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/blob/4339357ee536333f8c8cfcbee1a0aa7fd43cae3d/main/utils.zkasm#L1540
readFromCalldataOffset helper中未修改D寄存器,因此无需存储其之前值,并在结束时恢复原值。
建议:
- 移除tmpVarDReadXFromOffset变量,以及对D寄存器的存储和恢复代码。
修复PR见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/pull/23
3.4 信息类提示4:注释过期
上下文见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/blob/4339357ee536333f8c8cfcbee1a0aa7fd43cae3d/main/opcodes/create-terminate-context.zkasm#L388
- https://github.com/0xPolygonHermez/zkevm-rom-internal/blob/4339357ee536333f8c8cfcbee1a0aa7fd43cae3d/main/opcodes/create-terminate-context.zkasm#L625
- https://github.com/0xPolygonHermez/zkevm-rom-internal/blob/4339357ee536333f8c8cfcbee1a0aa7fd43cae3d/main/opcodes/create-terminate-context.zkasm#L744
- https://github.com/0xPolygonHermez/zkevm-rom-internal/blob/4339357ee536333f8c8cfcbee1a0aa7fd43cae3d/main/opcodes/create-terminate-context.zkasm#L830
CALL和CREATE opcodes中的注释,所描述的上下文与修复后的实现不匹配。
; copy calldata from origin CTX to current CTX
建议:
- 重写这些注释,以反映新方法实现。
修复PR见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/pull/23
3.5 信息类提示5:不需要的标签
上下文见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/blob/4339357ee536333f8c8cfcbee1a0aa7fd43cae3d/main/utils.zkasm#L1142
由本PR添加的addBatchHashByteByByteEnd标签,实际未被使用且与本修复无关。
建议:
- 移除该标签。
修复PR见:
- https://github.com/0xPolygonHermez/zkevm-rom-internal/pull/23
附录:Polygon Hermez 2.0 zkEVM系列博客
- ZK-Rollups工作原理
- Polygon zkEVM——Hermez 2.0简介
- Polygon zkEVM网络节点
- Polygon zkEVM 基本概念
- Polygon zkEVM Prover
- Polygon zkEVM工具——PIL和CIRCOM
- Polygon zkEVM节点代码解析
- Polygon zkEVM的pil-stark Fibonacci状态机初体验
- Polygon zkEVM的pil-stark Fibonacci状态机代码解析
- Polygon zkEVM PIL编译器——pilcom 代码解析
- Polygon zkEVM Arithmetic状态机
- Polygon zkEVM中的常量多项式
- Polygon zkEVM Binary状态机
- Polygon zkEVM Memory状态机
- Polygon zkEVM Memory Align状态机
- Polygon zkEVM zkASM编译器——zkasmcom
- Polygon zkEVM哈希状态机——Keccak-256和Poseidon
- Polygon zkEVM zkASM语法
- Polygon zkEVM可验证计算简单状态机示例
- Polygon zkEVM zkASM 与 以太坊虚拟机opcode 对应集合
- Polygon zkEVM zkROM代码解析(1)
- Polygon zkEVM zkASM中的函数集合
- Polygon zkEVM zkROM代码解析(2)
- Polygon zkEVM zkROM代码解析(3)
- Polygon zkEVM公式梳理
- Polygon zkEVM中的Merkle tree
- Polygon zkEVM中Goldilocks域元素circom约束
- Polygon zkEVM Merkle tree的circom约束
- Polygon zkEVM FFT和多项式evaluate计算的circom约束
- Polygon zkEVM R1CS与Plonk电路转换
- Polygon zkEVM中的子约束系统
- Polygon zkEVM交易解析
- Polygon zkEVM 审计及递归证明
- Polygon zkEVM发布公开测试网2.0
- Polygon zkEVM测试集——创建合约交易
- Polygon zkEVM中的Recursive STARKs
- Polygon zkEVM的gas定价
- Polygon zkEVM zkProver基本设计原则 以及 Storage状态机
- Polygon zkEVM bridge技术文档
- Polygon zkEVM Trustless L2 State Management 技术文档
- Polygon zkEVM中的自定义errors
- Polygon zkEVM RPC服务
- Polygon zkEVM Prover的 RPC功能
- Polygon zkEVM PIL技术文档
- Polygon zkEVM递归证明技术文档(1)【主要描述了相关工具 和 证明的组合、递归以及聚合】
- Polygon zkEVM递归证明技术文档(2)—— Polygon zkEVM架构设计
- Polygon zkEVM递归证明技术文档(3)——代码编译及运行
- Polygon zkEVM递归证明技术文档(4)—— C12 PIL Description
- Polygon zkEVM递归证明技术文档(5)——附录:借助SNARKjs和PIL-STARK实现proof composition
- eSTARK:Polygon zkEVM的扩展STARK协议——支持lookup、permutation、copy等arguments(1)
- eSTARK:Polygon zkEVM的扩展STARK协议——支持lookup、permutation、copy等arguments(2)
- eSTARK:Polygon zkEVM的扩展STARK协议——支持lookup、permutation、copy等arguments(3)
- Polygon zkEVM的Dragon Fruit和Inca Berry升级
- Polygon zkEVM协议治理、升级及其流程
- Polygon zkEVM 节点软件release日志
- Polygon zkEVM bridge服务 release日志
- Polygon zkEVM DataStreamer
- Polygon zkEVM Goldilocks域各项运算性能
- Polygon zkEVM Hexens审计报告解读
- Polygon zkEVM Spearbit审计报告解读(2022年12月版本)
- Polygon zkEVM Spearbit审计报告解读(2023年1月版本)
- Polygon zkEVM Spearbit审计报告解读(2023年3月版本)
- Polygon zkEVM ROM Spearbit审计报告解读(2023年6月Dragon Fruit升级版本)