我對我開發的庫中存在一個潛在的緩衝區溢出存在疑問,那裏有以下可以從外部應用程序調用的API。我試圖找到一個可能的解決方案,但我還沒有找到「正確的」解決方案。該API如下:仔細檢查一下緩衝區的大小
char* strftime_ISO8601(uint64_t ns, char* buf, size_t buflen) {
if (buf) {
//The standard format ISO 8601 is 20 bytes + 1 null
char datetime[21];
struct tm tm;
struct timespec ts = //convert nanoseconds into timespec
gmtime_r(&ts.tv_sec, &tm);
strftime(datetime, sizeof(datetime), "+%FT%T", &tm);
snprintf(buf, buflen, "%s.%.9ld", datetime, ts.tv_nsec);
}
return buf;
}
我需要提供足夠安全的代碼來防止「緩衝區溢出」。因爲這個原因,我使用了snprintf,其中目標緩衝區的大小作爲參數給出,結果字符串以NULL結尾。 我還使用一些靜態分析工具,如RATS來突出顯示潛在的漏洞。在這種情況下,我有以下注意事項:
Double check that your buffer is as big as you specify. When using functions that accept a number n of bytes to copy, such as strncpy, be aware that if the destination buffer size = n it may not NULL-terminate the string.
上的snprintf
snprintf(buf, buflen, "%s.%.9ld", datetime, ts.tv_nsec);
使用的snprintf我敢肯定,該字符串以NULL結尾,但我怎麼能如果仔細檢查輸入中給出的緩衝區的大小實際上是buflen?
我的意思是,如果用戶調用的API大小不正確,
...
char bad[5]
strftime_ISO8601(x, bad, 1024);
....
或甚至最壞使用一個未初始化的緩衝器是這樣的:
...
char *bad;
strftime_ISO8601(x, bad, 1024);
...
的一部分從一個潛在的段錯誤,我沒有看到上述API中任何特定的漏洞。但是,如何驗證API作爲輸入接收的buflen是否大小合適?
謝謝大家!
輕微:爲什麼'「+」'在'「+%FT%T」'?根據[ISO8601](http://en.wikipedia.org/wiki/ISO_8601),如果year值存在於範圍0-9999之外,那麼似乎只需要'+',在這種情況下'char datetime [21];'是太小。 – chux
輕微:在嘗試使用''%F''時,'+'或'-'都可以在需要時添加。建議刪除'+'並使用更大的緩衝區。 – chux