前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【链安科技】EOS资产Asset乘法运算溢出漏洞

【链安科技】EOS资产Asset乘法运算溢出漏洞

作者头像
辉哥
发布2018-08-22 11:06:33
7560
发布2018-08-22 11:06:33
举报
文章被收录于专栏:区块链入门区块链入门

综述

asset是EOS官方头文件中提供的用来代表货币资产(如官方货币EOS或自己发布的其它货币单位)的一个结构体。在使用asset进行乘法运算(operator *=)时,由于官方代码的bug,导致其中的溢出检测无效化。造成的结果是,如果开发者在智能合约中使用了asset乘法运算,则存在发生溢出的风险。

漏洞细节

问题代码存在于contracts/eosiolib/asset.hpp:

image

可以看到,这里官方代码一共有3处检查,用来防范溢出的发生。不幸的是,这三处检查没有一处能真正起到作用。

首先我们来看检查(2)和(3),比较明显,它们是用来检查乘法的结果是否在合法取值范围[-max_amouont, max_amount]之内。这里的问题是他们错误地被放置在了amouont *= a这句代码之前,正确的做法是将它们放到amouont *= a之后,因为它的目的是检测运算结果的合法性。正确的代码顺序应该是这样:

image

下面来看检测(1),这是一个非常重要的检测,目的是确保两点:

1.乘法结果没有导致符号改变(如两个正整数相乘,结果变成了负数)

2.乘法结果没有溢出64位符号数(如两个非零正整数数相乘,结果比其中任意一个都小)

image

这里的问题非常隐晦,直接看C++源代码其实看不出什么问题。但是我们要知道,EOS的智能合约最终是编译成webassembly字节码文件来执行的,让我们来看看编译后的字节码长什么样子:

image

上述字节码对应于源码中的:

image

这个结果让我们非常吃惊,应为很明显,生成的字节码代表的含义是:

image

相当于说这个assert的条件变成了永远是true,这里面的溢出检测就这样凭空消失了!!!

根据我们的经验,会发生这样的问题,很可能是编译器优化导致的。于是我们查看了一下官方提供的编译脚本(eosiocpp):

image

可以看到它是调用clang进行编译的,并且默认开启了编译器优化,优化级别是O3,比较激进的一个级别。

我们尝试关闭编译器优化(使用-O0),然后重新编译相同的代码,这次得到的对应字节码如下:

image

可以看到这次生成的字节码中完整保留了溢出检测的逻辑,至此我们可以确定这个问题是编译器优化造成的。

为什么编译器优化会导致这样的后果呢?这是因为在下面的语句中,amount和a的类型都是有符号整数:

image

在C/C++标准中,有符号整数的溢出属于“未定义行为(undefined behavior)”。当出现未定义行为时,程序的行为是不确定的。所以当一些编译器(包括gcc,clang)做优化时,不会去考虑出现未定义行为的情况(因为一旦出现未定义行为,整个程序就处于为定义状态了,所以程序员需要自己在代码中去避免未定义行为)。简单来讲,在这个例子里面,clang在做优化时不会去考虑以下乘法出现溢出的情况:

image

那么在不考虑上面乘法溢出的前提下,下面的表达式将永远为true:

image

于是一旦打开编译器优化,整个表达式就直接被优化掉了。

漏洞的危害

由于asset乘法中所有的三处检测通通无效,当合约中使用asset乘法时,将会面临所有可能类型的溢出,包括:

  1. a > 0, b > 0, a * b < 0
  2. a > 0, b > 0, a * b < a
  3. a * b > max_amount
  4. a * b < -max_amount

响应建议

对于EOS开发者,如果您的智能合约中使用到了asset的乘法操作,我们建议您更新对应的代码并重新编译您的合约。因为像asset这样的工具代码是静态编译进合约中的,必须重新编译才能解决其中的安全隐患。

同时,我们也建议各位EOS开发者重视合约中的溢出问题,在编写代码时提高安全意识,避免造成不必要的损失。

本文转载自《Asset乘法运算溢出漏洞》,已获得原作者授权

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.08.11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 综述
  • 漏洞的危害
  • 响应建议
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档