用更安全的C-string操控來減少溢出
發(fā)布時間:2008-04-06 閱讀數: 次 來源:網樂原科技
幾十年以來,在和里所聲明的標準C函數已經由于緩沖區(qū)溢出的問題,成為錯誤和安全漏洞的沃土。盡管專家建議的解決辦法是遷移到C++的和庫,但是這并不總是可能的。
最近一項關于在很多流行的應用程序和操作系統(tǒng)里同安全相關的錯誤的研究表明,C-string函數所使用的范圍要比我們想像的大得多。下面的提示會告訴你可以如何輕易地提高代碼的安全系數,即使它使用的是標準的C函數。
C99標準包括了新的函數,它們能夠明確地檢查緩沖區(qū)的大小,因此可以減少溢出的機會。想一想下面這個有問題的例子:
void f(const char *p)
{
char buf[11]={0};
sprintf(buf,"%10s",p); //very dangerous
printf("%s\n",buf);
}
不要讓格式標記"%10s"誤導了你。如果p碰巧大于10個字符,那么sprintf()所寫的內容就會超出buf的邊界,從而導致緩沖區(qū)的溢出:
f("hello world!"); //12 characters + nul
檢查出這樣的問題并不容易,因為它們只會在p大于10個字符的時候發(fā)生。黑客們常常會尋找這樣容易出錯的代碼,以闖入看上去很安全的系統(tǒng)。要解決這個問題,就要把sprintf()替換成snprintf(),這樣就有了下面的內容:
int
snprintf(char* buf, size_tmaxlen, const char* fmt, ...);
第二個自變量定義了寫入到buf的字符的最大數量,而不管格式標記和源字符串的大?。?br>
snprintf(buf, 10, "%10s",p); //now safe
f("hello world!"); //string is chopped to "hello worl\0"
類似的,你要分別使用strncpy()、strncmp()、strncat()、strnicmp()和strnset(),而不要使用strcpy()、strcmp()、strcat()、stricmp()和strset()。例如:
const int LINE_SIZE=81;
char buf[LINE_SIZE]={0};
// write up to 80 chars to buf:
strncpy(buf, dest, LINE_SIZE-1);
// compare no more than 80 chars:
int equal= strncmp(buf, dest, LINE_SIZE-1);
使用限制了緩沖區(qū)的C函數能夠減少緩沖區(qū)溢出的可能性,而不需要改動很多的原始代碼。