用這個代碼片段有可能是錯誤的(在軟件安全性方面),我似乎無法弄清楚......函數在顯示字符串參數後終止程序。c代碼片段中的安全缺陷?
void get_user(char* user)
{
char buf[1024];
if (strlen(user) > sizeof(buf))
die("error: user string too long\n");
strcpy(buf, user);
…
}
-thx!
用這個代碼片段有可能是錯誤的(在軟件安全性方面),我似乎無法弄清楚......函數在顯示字符串參數後終止程序。c代碼片段中的安全缺陷?
void get_user(char* user)
{
char buf[1024];
if (strlen(user) > sizeof(buf))
die("error: user string too long\n");
strcpy(buf, user);
…
}
-thx!
它不計算NUL(\0
)終止的字符串。
if (strlen(user) >= sizeof(buf))
這是不安全的,如果user
有1024個字符(會寫0
某處在堆棧上)。
儘管'strlen(user)+ 1'的病態實現可能會溢出,原則上最好使用'> ='運算符而不是加法來避免數值溢出問題。 –
@R ..這很有趣;你能詳細瞭解溢出問題嗎? – cnicutar
'strlen(user)+ 1'不能溢出,因爲字符串對象的實際大小包含空終止符。但是,假設你想知道'size1'和'size2'的對象是否可以放在一個緩衝區中。 'if(size1 + size2> available)'不是一個正確的測試,因爲添加大小可能會換行(如果它們是未簽名的)或溢出並給予UB(如果它們是已簽名的)。因此,至少在我看來,這種形式的條件是*代碼氣味* - 它們表明潛在的安全缺陷,並需要進一步閱讀以確定代碼是否實際上是安全的。 –
如果strlen(user)
等於1024,strcpy
將在buf
的末尾寫入一個字節。
的問題是在這裏:
if (strlen(user) > sizeof(buf))
這並不佔空終止時strlen(user) == sizeof(buf)
。該檢查應
if (strlen(user) > sizeof(buf) - 1)
使strcpy()
可以隨時複製空終止。
有一個可能導致緩衝區溢出的錯誤的錯誤。請記住,strlen會爲您提供字符串中的字符數,,不包括空終止符。檢查應該是:
if (strlen(user) + 1 > sizeof(buf))
從strlen的手冊頁:
所述的strlen()函數計算的字符串s的長度,不 包括終止 '\ 0' 字符。
並從strcpy的手冊頁:
的的strcpy()函數將字符串由src指出,包括 終止空字節( '\ 0'),到緩衝區指向DEST。
尺寸比較存在不匹配。代碼檢查字符串長度是否小於緩衝區,但複製字符串長度爲+1個字符。如果字符串長度(小於終止'\ 0')爲1024,則會發生溢出。
這功課嗎? – Skizz