安全編碼 筆記簡單摘要《C和C++安全編碼(原書第2版)》


常見字符串操作錯誤

場景

注解

無界字符串復制

1、無界字符串復制發生於從源數據復制數據到一個定長的字符數組時

2、復制和連接字符串。復制和連接字符串時也容易出現錯誤,因為執行這個功能的許多標准庫調用,如strcpy()  strcat()和sprJntf()函數,執行無界復制操作。

主要考慮目的數據的可容納空間大小。

差一錯誤(off-by-one error)

差一錯誤與無界 字符串復制有相似之處.即都涉及對數組的越界寫問題。

復制循環多一次或少一次。

空字符結尾錯誤

空字符結尾的字符串的另一個常見問題,根據C標准,strncpy()函數從源數組復制不超過n個字符。

字符串未能正確的以空字符結尾。

字符串截斷

目標字符數組長度不足以容納一個字符串內容時。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 要檢測和處理輸入輸出錯誤
  • 容易發生緩沖區溢出的問題

□將字符串定義為以空字符結尾的字符數組

□未進行隱式的邊界檢査

□提供了未強制性邊界檢査的標准字符串函數調用

 

 

 

 

字符串漏洞緩解辦法:

《C安全編碼標准》[Seacord 2008], 44 STR01-C.采用並實現一個管理字符串的一致計划” 建議選擇一種方法來處理字符串並在項目中始終如一地執行。否則,決定權就落到了單個程序員身上,他們很可能采取不同、不一致的方法。

 

atexit函數 cyg_libc_invoke_atexit_handlers由exit函數調用,該函數調用被atexit注冊過的函數。

常見的與內存管理相關 的編程缺陷包括:初始化錯誤、未檢查返回值、對空指針或無效指針解引用、引用已釋放的 內存、對同一塊內存釋放多次、內存泄漏和零長度分配。

 

常見內存管理錯誤

現象

備注

初始化錯誤

通常用函數malloc(〉分配內存塊。由malloc()返回的空間中的值是不確定的。

1、一個常見的錯誤是不正確地假設malloc()把分配的內存的所有位都初始化為零。《C安全編碼標 准》[Seacord 2008] "MEM09-C.不要假定內存分配函數初始化內存”進一步描述了這個問題。 未能遵循這一建議可能會導致違反“EXP33・C.不要引用未初始化的內存”。

2、正如《C安全編碼標准》[Seacord 2008]中的MEM03-C推薦的:“清 除存儲在可重復使用的資源中的敏感信息”清除或覆寫內存通常是通過調用C標准的 memset() 數來完成的。遺憾的是,如果不在寫后訪問內存,編譯器優化可能會默默地刪 除對memset()的調用。為了避免這種可能性,你可以使用C標准附錄K (如果可用)中 定義的memset_s()函數。不同於memset(), memset_s()函數假定被設置的內存可能 會在未來被訪問,因此這個函數調用不能被優化掉。詳情參見《C安全編碼標准》[Seacord 2008] “MSC06・C.處理敏感數據時,要注意編譯器優化"以獲得更多信息。

free與malloc都不需要清除內存。

未檢查返回值

編寫應用程序的程序員必須確定何時發生了錯誤,並以適當的方式處理該錯誤。因此, 《C安全編碼標准》[Seacord 2008] ° MEM32-C.檢測和處理內存分配錯誤”要求檢測並妥善管理這些錯誤。

 

NULL或無效指針的訪問(解引用)

確保malloc返回的不是空指針。不要執行0長度分配

 

引用已釋放的內存

 

free無法把它的指針參數設置為NULL。因為它需要一個void **類型的參數,而不是void *類型的參數

多次釋放內存

 

 

 

釋放(double-free)這個錯誤是危險的,因為它會以一種不會立即顯現的方式破壞內存管理 器中的數據結構。因為許多程序員沒有意識到,多次釋放相同的內存會導致可以利用的漏洞, 從而加劇了這個問題的危險性。

內存泄漏、0長度分配

c標准規定:

如果所要求的空間大小是零,其行為是實現定義的:要么返回一個空指針,要么除了不 得使用返回的指針來訪問對象以外,行為與大小仿佛是某個非零值。

不要分配0 字節

 

基於堆的內存管理缺陷緩解

措施

實踐

局限

空指針

指針所引用的內存被釋放后,將此指針設置為NULL。

如果多個指針指向同一個數據結構,這樣的規避還是無法避免因覆寫已經釋放內存,和雙重釋放而引起的漏洞

采取一致的內存管理約定

  • 使用同樣的模式分配和釋放內存。
  • 在同一個模塊中,在同一個抽象層次中分配和釋放內存。
  • 讓分配和釋放配對。

c++中構造負責所有內存的分配,析構函數進行所有內存的釋放。

在子例程中釋放內存會導致 混亂:究竟內存是否被釋放了?何時釋放的?在哪兒釋放的?

phkmalloc,隨機化,OpenBSD,jemalloc,靜態分析,動態分析。

PurifyPlus。Valgrind。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

摘抄自讀書筆記,有同樣心得的網友可以交流分享下。

同時可以參考書籍:

sei-cert-c-coding-standard-2016-v01

https://github.com/fogcell/learnfist/blob/master/pdf_book/sei-cert-c-coding-standard-2016-v01.pdf


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM