2015-06-03 44 views
0

我對我開發的庫中存在一個潛在的緩衝區溢出存在疑問,那裏有以下可以從外部應用程序調用的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是否大小合適?

謝謝大家!

+0

輕微:爲什麼'「+」'在'「+%FT%T」'?根據[ISO8601](http://en.wikipedia.org/wiki/ISO_8601),如果year值存在於範圍0-9999之外,那麼似乎只需要'+',在這種情況下'char datetime [21];'是太小。 – chux

+0

輕微:在嘗試使用''%F''時,'+'或'-'都可以在需要時添加。建議刪除'+'並使用更大的緩衝區。 – chux

回答

1

簡單地說 - 你不能...
沒有辦法確定你收到的指針的「長度」作爲指針,因爲沒有實體可以在運行時驗證它。這就是您首先要求長度的原因!

在你的情況下,唯一的解決辦法是給自己分配的內存,並返回給用戶,轉移爲內存管理用戶的責任:

char* strftime_ISO8601(uint64_t ns) { 
    //The standard format ISO 8601 is 20 bytes + 1 null 
    char datetime[21]; 
    char *res = malloc(EXPECTED_SIZE) 
    struct tm tm; 
    struct timespec ts = //convert nanoseconds into timespec 

    gmtime_r(&ts.tv_sec, &tm); 
    strftime(datetime, sizeof(datetime), "+%FT%T", &tm); 
    snprintf(res, EXPECTED_SIZE, "%s.%.9ld", datetime, ts.tv_nsec); 

    return res; 
} 

這樣,你是在控制內存分配,從而可以防止緩衝區溢出

+0

非常感謝!我會考慮爲該庫的未來版本重新分配此API! – IWill80