【鏈安科技】EOS資產Asset乘法運算溢出漏洞

綜述

asset是EOS官方頭文件中提供的用來代表貨幣資產(如官方貨幣EOS或自己發(fā)布的其它貨幣單位)的一個結構體。在使用asset進行乘法運算(operator *=)時,由于官方代碼的bug肿轨,導致其中的溢出檢測無效化寿冕。造成的結果是,如果開發(fā)者在智能合約中使用了asset乘法運算椒袍,則存在發(fā)生溢出的風險驼唱。

漏洞細節(jié)

問題代碼存在于contracts/eosiolib/asset.hpp:

image

可以看到,這里官方代碼一共有3處檢查驹暑,用來防范溢出的發(fā)生玫恳。不幸的是,這三處檢查沒有一處能真正起到作用优俘。

首先我們來看檢查(2)和(3)京办,比較明顯,它們是用來檢查乘法的結果是否在合法取值范圍[-max_amouont, max_amount]之內帆焕。這里的問題是他們錯誤地被放置在了amouont *= a這句代碼之前惭婿,正確的做法是將它們放到amouont *= a之后,因為它的目的是檢測運算結果的合法性叶雹。正確的代碼順序應該是這樣:

image

下面來看檢測(1)财饥,這是一個非常重要的檢測,目的是確保兩點:

1.乘法結果沒有導致符號改變(如兩個正整數相乘折晦,結果變成了負數)

2.乘法結果沒有溢出64位符號數(如兩個非零正整數數相乘钥星,結果比其中任意一個都小)

image

這里的問題非常隱晦满着,直接看C++源代碼其實看不出什么問題谦炒。但是我們要知道,EOS的智能合約最終是編譯成webassembly字節(jié)碼文件來執(zhí)行的风喇,讓我們來看看編譯后的字節(jié)碼長什么樣子:

image

上述字節(jié)碼對應于源碼中的:

image

這個結果讓我們非常吃驚宁改,應為很明顯,生成的字節(jié)碼代表的含義是:

image

相當于說這個assert的條件變成了永遠是true响驴,這里面的溢出檢測就這樣憑空消失了M盖摇!豁鲤!

根據我們的經驗秽誊,會發(fā)生這樣的問題,很可能是編譯器優(yōu)化導致的琳骡。于是我們查看了一下官方提供的編譯腳本(eosiocpp):

image

可以看到它是調用clang進行編譯的锅论,并且默認開啟了編譯器優(yōu)化,優(yōu)化級別是O3楣号,比較激進的一個級別最易。

我們嘗試關閉編譯器優(yōu)化(使用-O0)怒坯,然后重新編譯相同的代碼,這次得到的對應字節(jié)碼如下:

image

可以看到這次生成的字節(jié)碼中完整保留了溢出檢測的邏輯藻懒,至此我們可以確定這個問題是編譯器優(yōu)化造成的剔猿。

為什么編譯器優(yōu)化會導致這樣的后果呢?這是因為在下面的語句中嬉荆,amount和a的類型都是有符號整數:

image

在C/C++標準中归敬,有符號整數的溢出屬于“未定義行為(undefined behavior)”。當出現未定義行為時鄙早,程序的行為是不確定的汪茧。所以當一些編譯器(包括gcc,clang)做優(yōu)化時限番,不會去考慮出現未定義行為的情況(因為一旦出現未定義行為舱污,整個程序就處于為定義狀態(tài)了,所以程序員需要自己在代碼中去避免未定義行為)弥虐。簡單來講扩灯,在這個例子里面,clang在做優(yōu)化時不會去考慮以下乘法出現溢出的情況:

image

那么在不考慮上面乘法溢出的前提下躯舔,下面的表達式將永遠為true:

image

于是一旦打開編譯器優(yōu)化驴剔,整個表達式就直接被優(yōu)化掉了。

漏洞的危害

由于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開發(fā)者惜互,如果您的智能合約中使用到了asset的乘法操作,我們建議您更新對應的代碼并重新編譯您的合約琳拭。因為像asset這樣的工具代碼是靜態(tài)編譯進合約中的训堆,必須重新編譯才能解決其中的安全隱患。

同時白嘁,我們也建議各位EOS開發(fā)者重視合約中的溢出問題坑鱼,在編寫代碼時提高安全意識,避免造成不必要的損失絮缅。

本文轉載自《Asset乘法運算溢出漏洞》鲁沥,已獲得原作者授權

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市耕魄,隨后出現的幾起案子画恰,更是在濱河造成了極大的恐慌,老刑警劉巖吸奴,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件允扇,死亡現場離奇詭異缠局,居然都是意外死亡,警方通過查閱死者的電腦和手機考润,發(fā)現死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門狭园,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人糊治,你說我怎么就攤上這事妙啃。” “怎么了俊戳?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵揖赴,是天一觀的道長。 經常有香客問我抑胎,道長燥滑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任阿逃,我火速辦了婚禮铭拧,結果婚禮上,老公的妹妹穿的比我還像新娘恃锉。我一直安慰自己搀菩,他們只是感情好,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布破托。 她就那樣靜靜地躺著肪跋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪土砂。 梳的紋絲不亂的頭發(fā)上州既,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音萝映,去河邊找鬼吴叶。 笑死,一個胖子當著我的面吹牛序臂,可吹牛的內容都是我干的蚌卤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼奥秆,長吁一口氣:“原來是場噩夢啊……” “哼逊彭!你這毒婦竟也來了?” 一聲冷哼從身側響起吭练,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤诫龙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鲫咽,有當地人在樹林里發(fā)現了一具尸體签赃,經...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡谷异,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了锦聊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歹嘹。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖孔庭,靈堂內的尸體忽然破棺而出尺上,到底是詐尸還是另有隱情,我是刑警寧澤圆到,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布怎抛,位于F島的核電站,受9級特大地震影響芽淡,放射性物質發(fā)生泄漏马绝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一挣菲、第九天 我趴在偏房一處隱蔽的房頂上張望富稻。 院中可真熱鬧,春花似錦白胀、人聲如沸椭赋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哪怔。三九已至,卻和暖如春廷痘,著一層夾襖步出監(jiān)牢的瞬間蔓涧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工笋额, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人篷扩。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓兄猩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鉴未。 傳聞我的和親對象是個殘疾皇子枢冤,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內容