{ 跳至内容 }

Solidity 优化器漏洞

作者:Martin Swende 发布于 2017年5月3日

安全警报

此文章最初发布在以太坊博客.

Christoph Jentzsch 通过 以太坊基金会赏金计划 报告了 Solidity 优化器中的一个漏洞。此漏洞已于 2017-05-03 通过发布 Solidity 0.4.11 进行修复。

背景

该漏洞涉及优化器如何优化字节码中的常量。这里所说的“字节码常量”是指任何PUSH 到堆栈上的内容(不要与 Solidity 常量混淆)。例如,如果值 0xfffffffffffffffffffffffffffffffffffffffffffffffePUSH,则优化器可以选择执行 PUSH32 0xfffffffffffffffffffffffffffffffffffffffffffffffe,或者选择将其编码为 PUSH1 1; NOT;

优化器中的错误导致在某些情况下字节码常量的优化失败,产生了无法正确重现原始常量的例程。

在报告的漏洞中描述的行为是在一个合约中发现的,其中一个方法在向合约中添加另一个完全无关的方法后停止工作。经过分析,确定触发此漏洞需要同时存在多个条件。任何触发此漏洞的条件组合都将始终包含以下两个条件

  • 常量需要以 0xFF... 开头并以一系列零结尾(反之亦然)。
  • 相同的常量需要在多个位置使用,以便优化器选择优化此特定常量。或者,它需要在构造函数中使用,构造函数会为了大小而非 Gas 进行优化。

除了上述两个条件外,还需要满足其他更复杂的条件。

分析

此漏洞存在于至少从 2015 年夏季到现在的所有已发布的 Solidity 版本中。尽管此漏洞自 2015 年以来就已存在,但似乎很难通过“随机”代码触发。

我们对区块链上部署的所有合约代码进行了静态分析,但未发现此类无效生成的例程。请注意,我们没有在所有合约代码中发现此漏洞并不保证此类情况不存在。

改进

为了提供更好的透明度和提高对 Solidity 中漏洞的认识,我们已开始以 JSON 文件的形式在 Solidity 代码库中导出有关 Solidity 相关漏洞的信息(12)。我们希望区块浏览器能够将此信息与其他合约相关信息一起集成。

Etherscan 已经实现了这一点,可以在 此处此处 查看。

关于漏洞本身,我们在优化器中添加了一个迷你 EVM,它在编译时验证每个生成的例程的正确性。

此外,已经开始着手开发一个完全指定的、更高级别的中间语言。未来在此语言上的优化器例程将更容易理解和审计,并将取代当前的优化器。

上一篇

下一篇

参与进来

GitHub

Twitter

Mastodon

矩阵

了解更多

博客文档使用案例贡献关于论坛

2024Solidity 团队

安全策略

行为准则