簡體   English   中英

什么C / C ++函數最常使用不正確,可能導致緩沖區溢出?

[英]What C/C++ functions are most often used incorrectly and can lead to buffer overflows?

我被要求維護一個充滿內存泄漏的大型C ++代碼庫。 在探索時,我發現我們有很多緩沖區溢出導致泄漏(它如何變壞,我不想知道)。

我決定先從危險函數開始刪除緩沖區溢出。 哪些C / C ++函數最常使用不正確並可能導致緩沖區溢出?

對於用於幫助查找緩沖區溢出的編譯器和/或工具,我創建了另一個處理此問題的問題

通常,任何不檢查參數中的邊界的函數。 列表將是

  • 得到()
  • scanf()函數
  • 的strcpy()
  • strcat的()

您應該使用大小限制版本,如stncpy,strncat,fgets等。然后在給出大小限制時要小心; 考慮'\\ 0'終止字符串。

此外,數組未在C或C ++中進行檢查。 以下示例將導致錯誤。 看到一個錯誤

int foo[3];
foo[3] = WALKED_OFF_END_OF_ARRAY;

編輯 :@MrValdez,@ Denton Gentry的復制答案

Valgrind是你最好的朋友。

valgrind --tool = memcheck --leak-check = full ./a.out

我擔心問題是從錯誤的一端開始。 它假設緩沖區溢出發生在其他函數中。 根據我的經驗,最常見的原因是operator ++,或者缺少運算符!=。

在Visual Studio 2005/8中找到一批這些批處理的最佳解決方案是/ GS。 它不會找到所有這些,但它是減少所需手工工作量的廉價方法。

以下是我發現的一些危險的功能:

  • gets() - 它不檢查變量的長度,如果輸入大於變量的緩沖區,則可以覆蓋內存。
  • scanf() - 我很高興Visual Studio告訴我這個函數已被棄用。 這是一個簡單的解決方案。
  • strcpy() - 如果源的內存空間大於目標的內存空間,則覆蓋目標之后的數據。

以下鏈接應該讓您全面了解C ++中的安全功能(使用'_s'進行后置修復以解決溢出等問題): http//msdn.microsoft.com/en-us/library/8ef0s5kh( VS.80)的.aspx

編輯:此鏈接包含已被替換的特定功能: http//msdn.microsoft.com/en-us/library/wd3wzwts(VS.80).aspx

編輯:我應該提到這些是Microsoft方法,但該鏈接仍然有用於識別被視為紅旗的功能。

不幸的是,任何數組都可能導致緩沖區溢出:

uint32_t foo[3];
foo[3] = WALKED_OFF_END_OF_ARRAY;

在功能方面,sprintf將很樂意走出緩沖區的末端。 它可以被snprintf取代。

Memcpy()是另一個危險的。

訪問數組的任何循環都是一個危險點,因為沒有超出數組末尾的停止。

內存泄漏是由分配內存引起的,而不是釋放它。 構造函數和析構函數應該是另一個強有力的評論點,后者是為了確保任何已分配的內存都是自由的。

您使用的是哪個版本的visual studio? 在2008年啟用所有警告后,您提及的所有功能(以及更多)都會警告您已棄用它們。

也許您可以檢查是否已打開所有警告並讓編譯器為您完成了艱苦的工作?

作為旁注,優秀的寫作安全代碼可以很好地解釋一些舊功能的不同之處。

我在工作的代碼庫上有一些相同的問題。 我的建議:警惕任何看起來像str *()和mem *()的C函數。 還要注意任何指向緩沖區的指針,沒有長度。 由於您似乎有機會使用C ++,我會在最惡劣的情況下嘗試使用C ++容器來處理事物:矢量,字符串,地圖等。這些使您的生活更輕松。

此外,自動化問題檢測工具非常棒。 如果你可以使用valgrind我會推薦它。 Rational Purify也非常強大,但並不便宜。

C中的另一個問題是“strncpy()”函數。 許多人沒有意識到可以自由地返回一個非null終止的字符串。

基本上,任何接受指針並寫入指針而不檢查長度的東西。 所以像strcpy(),sprintf()等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM