二次釋放簡單理解就是對同一個指標指向的記憶體釋放了兩次,針對C語言原始碼,對同一個指標進行兩次 free() 操作,可能導致二次釋放,本文3.1章節的缺陷代碼就是這類情況的描述。在C 語言中,淺拷貝操作不當是導致二次釋放常見原因之一。如:呼叫一次賦值運算子或拷貝建構子將會導致兩個物件的資料成員指向相同的動態記憶體。此時引用計數機制變得非常重要,當引用計數不當時,一個物件超出作用域時,析構函數將會釋放這兩個物件共享的記憶體。另一個物件中對應的資料成員將會指向已經釋放的記憶體位址,而當這個物件也超出作用域時,它的析構函數試圖再次釋放這塊內存,導致二次釋放問題。詳細請參閱CWE ID 415: Double Free。
二次釋放記憶體可能導致應用程式崩潰、拒絕服務攻擊等問題,是C/C 中常見的漏洞之一。 2018年1月至11月,CVE中共有38個漏洞資訊與其相關。部分漏洞如下:
#CVE 編號 | |
---|---|
CVE-2018-18751 | GNU gettext 0.19.8 版本中的read-catalog.c 檔案的'defaultaddmessage' 函數存在二次釋放漏洞。 |
CVE-2018-17097 | Olli Parviainen SoundTouch 2.0 版本中的WavFile.cpp 檔案的WavFileBase 類別存在安全漏洞,遠端攻擊者可利用該漏洞造成拒絕服務(二次釋放)。 |
CVE-2018-16425 | #CVE-2018-16425 |
CVE-2018-16402 |
3、範例程式碼
3.1缺陷程式碼
#在上述範例程式碼中,第32行使用
malloc() 進行記憶體分配,並在第36行使用
free() 對分配的記憶體進行了釋放,在第38行
for
data
進行了一次釋放,導致二次釋放問題。使用360程式碼衛兵對上述範例程式碼進行偵測,可以檢出「二次釋放」缺陷,顯示等級為中。如圖1所示:
3.2 修正程式碼
#在上述修復程式碼中,Samate 給出的修復方式為: 在第32行使用
malloc()
free()
進行釋放,釋放後不在對該記憶體進行釋放操作。
使用360程式碼衛兵對修復後的程式碼進行偵測,可以看到已不存在「二次釋放」缺陷。如圖2:
圖2:修正後偵測結果
4 、如何避免二次釋放
###(3)使用原始碼靜態分析工具,可以自動化的發現程式中可能存在的二次釋放問題。 ######要避免二次釋放,需要注意以下幾點:
(1)野指標是導致二次釋放和釋放後使用的重要原因之一,消除野指標的有效方式是在釋放指標之後立即把它設為NULL
或設定為指向另一個合法的物件。 (2)針對 C 淺拷貝導致的二次釋放問題,始終執行深拷貝是不錯的解決方案。
以上是C語言源碼二次釋放的危害是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!