2014-03-31 61 views
0

前幾天我問了一個關於緩衝區溢出檢測的問題(sprintf buffer global data overflow - how to detect it, Windows),問題只能通過cppcheck用標準函數(不安全_s版本)解決。全局緩衝區溢出,Windows環境

我去更深,改變代碼

#include <stdio.h> 
char buffer[2]; 
void main() 
{ 
    sprintf(buffer,"12345"); 
} 

#include <stdio.h> 
void f(char *b) 
{ 
    sprintf(b,"12345"); 
} 

char buffer[2]; 
void main() 
{ 
    f(buffer); 
} 

的Visual Studio 2012/RTC可以處理堆棧分配的緩衝區溢出 - 在運行時,但全球數據撐未被發現。

我想這是不可能使用cppcheck進行深入分析,並且cppcheck-1.64未檢測到此問題。此外,我嘗試使用AddressSanitizer(Windows)的clang也沒有好的結果。

是可以防止Windows下的這些問題(免費工具最好),如果不是一些Linux工具可以幫助?

+0

總的來說,我發現只是沒有超過緩衝區的末端就簡單了。 –

+1

通常開發人員不會故意製造錯誤:) – bataliero1234

回答

0

而不是使用sprintf,你應該考慮使用snprintf。其原型(包含在頭部stdio.h) -

int snprintf(char *str, size_t size, const char *format, ...); 

功能至多size字節,其中包括終止空字節到緩衝str指向寫入。因此,您應該更改函數f簽名以獲取緩衝區的長度。另外,還要注意的main簽名應該是下列之一 -

int main(void); 
int main(int argc, char *argv[]); 

我建議以下變化 -

#include <stdio.h> 

void f(char *b, size_t len) { 
    sprintf(b, len, "12345"); 
} 

char buffer[2]; 
int main(void) { 
    f(buffer, sizeof buffer); 
    return 0; 
} 
0

這些都是一些由於我們應該避免全局變量的原因在我們的程序中。 我不認爲有這樣的工具存在會報告有關 全局變量(數據段)損壞。有很多可用的工具可用於檢測堆棧和堆段內存損壞/溢出。

因此爲了避免這種情況,我們應該儘量減少程序中全局變量 的使用。如果這是不可能的,我們應該嘗試使用防禦性編程方法 自己使用這些。只是爲了說明這一點,您的程序可以用以下方式重新編寫,以避免程序中出現全局內存損壞 的情況。

#include <cstdio> 

char buffer[2]; 


void f(char *b, size_t sz) 
{ 
// Now we have protected our global variable from overrun by 
// using the size information passed by caller.So even though 
// client "12345" has been passed, it would just copy 12. 
strncpy(b,"12345",sz); 
} 


int main() { 
    size_t tmp = sizeof(buffer)/sizeof(buffer[0]); 
    f(buffer, tmp); 
    return 0; 
} 
+0

因此,沒有工具可以將變量之間的金絲雀/魔術字放在數據段中(如堆棧溢出保護方法)?我thougt AddressSanitizer會做這樣的事情,但昨天我已經測試它,失敗檢測。 http://code.google.com/p/address-sanitizer/wiki/ComparisonOfMemoryTools – bataliero1234

+0

@ bataliero1234:有可能是工具,甚至AddressSanitizer可能工作。在處理全球(數據)部分時會有一些技術限制。但是,如果可能的話,我們應該使我們的程序更加健壯和安全(如果可能的話),並減少對工具的依賴。在大多數情況下,您的軟件會遇到一些您無法在我們自己的環境中重現的問題,這一點很重要。客戶不會(通常)允許您在其生產機器上運行任何動態工具。所以選擇是我們的:) –