C語言中常見的記憶體申請函數包括malloc()
、 realloc()
、 calloc()
,它們雖然功能不同,但都對應同一個記憶體釋放函數free()
,C 中對記憶體的申請和釋放採用new/delete、new [] /delete[] 方式。不管是 C 語言還是 C 語言,當編寫原始程式碼時要根據記憶體申請的方法不同來對應地選擇記憶體釋放方法,避免使用錯誤的記憶體釋放。例如:混合使用C/C 的記憶體申請/釋放,或混合使用標量和向量的記憶體申請/釋放。
錯誤地釋放記憶體可能會導致程式出現意料之外的錯誤行為,甚至導致程式崩潰。在《effective C (第二版)》條目5「對應的new 和delete 要採用相同形式」中指出:「如果錯誤地釋放物件中的元素,可能造成整個物件、甚至整個堆上的記憶體結構都會發生損壞,從而發生記憶體洩漏,甚至導致程式崩潰」。
在CVE資料庫中,也有與此相關的漏洞資訊。自2018年1月至2019年4月,CVE資料庫中共有3個相關漏洞資訊。漏洞資訊如下:
#CVE | 漏洞概況 |
---|---|
CVE-2018-14948 | dilawar sound2017-11-27 及先前版本中的wav-file.cc檔案存在錯誤的記憶體釋放方法漏洞(new[]/delete) 。 |
CVE-2018-14947 | PDF2JSON 0.69 版本中的XmlFonts.cc 檔案的'XmlFontAccu::CSStyle'函數有錯誤的記憶體釋放漏洞(new[] /delete)。 |
CVE-2018-14946 | PDF2JSON 0.69 版本中的 ImgOutputDev.cc 檔案的 HtmlString 類別存在錯誤的記憶體方法漏洞 (malloc/delete)。 |
範例源自於Samate Juliet Test Suite for C/C v1.3 (https:// samate.nist.gov/SARD/testsuite.php),原始檔名:CWE762_Mismatched_Memory_Management_Routines__new_array_delete_char_01.cpp。
#在上述範例程式碼中,第31行使用new[]
創建物件數組,在第34行使用delete
進行釋放,由於在釋放物件數組時,沒有使用new[]
對應的delete[]
,因此存在“錯誤的記憶體釋放方法”問題。
使用程式碼衛兵對上述範例程式碼進行偵測,可以檢出「錯誤的記憶體釋放方法」缺陷,顯示等級為中。如圖1所示:
圖1:錯誤的記憶體釋放方法的偵測範例
在上述修復程式碼中,Samate 給出的修復方式為:在第31行透過new[]
建立物件數組,並在第33行使用delete[]
進行釋放。從而避免了錯誤的記憶體釋放方法。
使用程式碼衛士對修復後的程式碼進行偵測,可以看到已不存在「錯誤的記憶體釋放方法」缺陷。如圖2:
圖2:修正後偵測結果
要避免錯誤的記憶體釋放方法,需要注意以下幾點:
(1)在進行記憶體釋放時,明確記憶體申請使用的方法,避免由於程式結構複雜、人員疏忽而導致使用了錯誤的釋放方法。
(2)使用原始碼靜態分析工具,可以有效對此類別問題進行偵測。
以上是【缺陷週話】第31期:錯誤的記憶體釋放的詳細內容。更多資訊請關注PHP中文網其他相關文章!