4、是的,我们说了一个多月(两个焦点)。我们运行了高出10亿次的编译,以便找到一些更隐晦的bug。这些错误在原始语料库的派生树中很是深。同样我们在Vyper编译器中发明的bug也需要很长时间才气发明。虽然假如你的恍惚化事情不只仅是玩弄一种新技能,你大概会想在这个问题上投入呆板(从而投入资金)。可是按照一篇重要的新论文,假如这是你独一的要领,你大概需要投入更多的呆板来办理这个问题。
contract C {
触发输入团结了汇编和常量,可是我们利用的语料库中没有包括这两者的文件,它们看起来很像。最靠近的是:
在尝试较量中,我们发明白一些利用普通的旧AFL陈诉的早期bug,而且我们利用新要领很容易发明的这些bug,我们在没有利用新要领的环境下,利用AFL举办复制这些bug-但大大都bug尚未被复制 在“普通” AFL中。下图显示了我们在GitHub上提交的bug数量,并强调了AFL变动的重要性:
}function f(uint x) public returns (uint y) {
let t := c
同时包括汇编和shl的最靠近的文件是:
像这样归并智能合约并非易事。没有一个实例与裂痕袒露条约中的特定shl表达式很是相似,甚至没有呈此刻语料库中的任那里所。试图修改汇编中的常量不太大概显示在正当代码中。并且我们认为手动发生如此奇怪但重要的输入是极其重要的。在这种环境下,就像恍惚测试常常产生的那样,假如您完全可以想到一个智能合约,就像触发该bug的智能合约,那么您或其他人大概一开始就可以编写正确的代码。
并且对付基于反馈的恍惚器,仅利用更多的呆板大概不会发生一些需要较长时间才气发明的艰涩的bug;也不必然老是有捷径可以达到需要对原始语料库路径举办突变的bug。利用一百万个“ clusterfuzz”实例会发生很大的广度,可是纵然这些实例按期共享互相的新颖路径,也不必然能到达深度。
纵然是我们的bug触发Solidity文件的未精简版本看起来也像Solidity源代码。这大概是因为AFL大力大举支持的我们的变异倾向于“保存源代码的y-ness”。好像正在产生的大部门环境是微小的变革的殽杂,这些微小的变革不会使文件变得过于谬妄,加上语料库示例的组合(AFL拼接)与普通的Solidity代码相距不远。AFL自己倾向于将源代码淘汰为不行编译的垃圾,纵然将其与有趣的代码归并,也不会使其超出初始编译器阶段。可是有了更会合的突变,拼接凡是就可以完成事情,因为在此输入中会触发仍然打开的错误(如我们所写):
}
}
}
function o (int256) public returns (int256) {
assembly { y := shl(2, x) }
虽然纵然有这样的事情,你也需要知道你在做什么,可能至少知道如安在网络上查找。没有什么能汇报您,仅仅用AFL编译solc实际上不会发生精采的恍惚化。首先需要留意的是,恍惚化会导致很是高的映射密度,这将丈量您“填充”AFL的包围散列的水平。然后您要么需要知道AFL用户指南中给出的发起,要么搜索术语“AFL map density”,并查察是否需要从头编译整个系统,将AFL_INST_RATIO配置为10,以使恍惚器更容易识别新路径。按照AFL文档,只有在“您要测试很是冗长的软件时”才会产生这种环境。所以假如你习惯了恍惚编译器,那么您大概以前曾经看过这种环境,可是不然您大概还没有碰着过映射密度问题。
3、您大概会留意到,提交的错误的最后一次岑岭产生在对我们的AFL-compiler-fuzzer存储库的最后一次提交之后很长时间。我们是否举办了尚不行见的当地变动?不,我们只是变动了用于恍惚测试的语料库。出格是,我们不只查察语法测试,还添加了我们可以在test/libsolidity下找到的所有Solidity源文件。完成的最重要的工作是答允我们查找SMT查抄器错误,因为它引入了利用SMTChecker编译指示的文件。假如没有利用该语料库的语料库示例,则AFL根基上没有时机摸索SMT Checker行为。
尺度AFL的变革不是出格大;该恍惚器仅添加了一些新的AFL粉碎性改变,基于文本的源代码突变测试东西(即universalmutator)所利用的突变。新要领只需要不到500行代码就可以实现,大大都代码都很是简朴且反复。
}
有些bug长短常简朴的问题。譬喻此智能合约用于导致编译器瓦解,并显示动静“Unknown exception during compilation:std::bad_cast”:
} catch Error(string memory) {
AFL的这种变革是Sourcegraph的Rijnard van Tonder,CMU的Claire Le Goues和犹他大学的John Regehr配合研究项目标一部门。在我们的劈头尝试中,将该要领与普通的AFL举办了较量,功效对付solc和Tiny C Compiler,tcc来说看起来不错。作为一门科学,该要领需要进一步开拓和验证。我们正在尽力。可是实际上,这种新要领险些可以必定地辅佐我们发明白solc中的很多新错误。 }
}
}
我们发明的其他后期bug(当好像不行能找到任何新错误时)主要来自成立“主”语料库,个中包罗到当时为止我们执行的每次恍惚测试所发生的每条有趣的路径,然后让恍惚测试了一个多月。
assembly {
1、本质上,我们在这个恍惚化测试中利用了AFL,但不并只是任何现成的AFL。取而代之的是,我们利用了AFL的一个新变体,它被明晰地设计用来辅佐开拓人员在不做太多特别事情的环境下恍惚C语言的语言东西。
try this() {
这是一次很是乐成的恍惚测试,据我们所知,这是有史以来最乐成的针对solc的进攻之一。这不是第一次用AFL来办理问题。通过AFL对solc举办恍惚化测试是一个恒久的实践。自2019年1月以来,该编译器甚至已经在OSSFuzz长举办了测试。我们如何设法找到这么多以前未发明的错误-在大大都环境下,值得快速修复的错误?以下是我们挑选出来的的五个重要因素。
另一方面,这个问题导致了bug嘉奖,并使其成为0.6.8编译器版本的重要bug修复列表,大概会为某些字符串文本生成错误代码。它还需要更多的代码来处理惩罚所需的价钱。
assembly {
contract C {
contract C {
int constant c=2 szabo+1 seconds+3 finney*3 hours;
在已往的几个月中,我们一直在对solc(尺度的Solidity智能合约编译器)举办恍惚测试,我们已经发明白近20个(此刻大部门已经修复)新的bug。个中一些是症状或触发器略与的现有bug差异,但绝大大都是编译器中以前未陈诉的bug。
结论
}
2、站在前人的肩膀上恍惚化一个从未被恍惚化过的系统必定是有效的;系统对恍惚器发生的各类输入的“抵挡力”大概很是低。可是恍惚化以前被恍惚化过的系统也有长处。正如我们所指出的,我们并不是第一个用AFL恍惚solc的人。编译器团队参加了solc的恍惚化,而且构建了一些东西,我们可以利用这些东西来简化事情。
在已经恍惚的高可见性软件中,比从不恍惚的软件中发明重要bug更坚苦。可是由于您回收了一些新颖的要领,基于以前的恍惚测试(出格是针对oracle,基本布局和语料库内容)的智能引导,再加上履历和专业常识,纵然在巨大的软件系统中也可以找到很多从未发明的bug,纵然 它们托管在OSSFuzz上。最后,纵然是我们最激进的恍惚处理惩罚也只能触及真正巨大的软件的外貌,就像现代出产编译器那样,,除了利用暴力之外,还需要必然的思考模式。
function f() public {
2月底,在我们为AFL版本添加了一些更智能的突变操纵之后,Bug发明的大幅度增长就呈现了。大概是巧合,但我们对此暗示猜疑。于是我们手动查抄了生成的文件,发明AFL恍惚行列内容产生了质的变革。另外,AFL生成的实际可编译Solidity文件的比例跃升了10%以上。
通过将typeError变动为fatalTypeError,可以轻松办理此问题,这可以防备编译器继承处于错误状态。提交修复仅是一行代码(尽量有许多行新测试)。
我们发明白什么?
function f() public returns (uint, uint) {
}
bool constant c = this;
5、提交之前淘汰bug触起源文件或实验遵循要向其陈诉bug的项目标实际问题提交准则没有什么奥秘。虽然纵然这些指南中没有提到,执行快速搜索以制止提交反复也是尺度操纵。我们做了那些事,并没有为我们的错误增加几多,可是他们虽然加速了将提交的问题识别为真正的bug并举办修复的进程。
contract C {
Solidity构建包罗一个名为solfuzzer的可执行文件,该文件将Solidity源文件作为输入,并利用各类选项(带有和不带有优化等)对其举办编译,以查找各类稳定的斗嘴和各类瓦解。我们发明的一些bug不会呈此刻普通的solc可执行文件中,除非您利用特定的呼吁行选项(出格是优化)或以某些其他很是不寻常的方法运行solc;solfuzzer发明白所有这些bug。我们还从其他人的履历中学到,AFL恍惚测试的一个很好的开始语料库在test/libsolidity/syntaxTests目次树中。这就是其他人所利用的,而且必定涵盖了许多“您大概在Solidity源文件中看到的内容”。
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。