2012-09-02 72 views
2

我決定在一些舊的代碼上運行一個靜態分析工具,並且發現了一些我正在使用sprintf的地方。該工具建議使用vsnprintf或snprintf替換調用,因爲sprintf不會對緩衝區溢出進行任何類型的邊界檢查。snprintf或vsnprintf更好,我如何確保我安全地使用它們?

我可以很容易地只是做了查找和調用替換,以便它使用的snprintf或vsnprintf代替,但我想,以確保沒有什麼別的需要,爲了使功能安全做

在某些情況下,使用的字符串來源於用戶輸入,在某些情況下它們不會。

有沒有人有任何建議如何做到這一點的權利?

+7

「snprintf或vsnprintf更好」這取決於您是否有可變參數或「va_list」。 – 2012-09-02 19:03:45

+0

便攜性是一個問題嗎? – robert

+0

不擔心可移植性,沒有。 – petFoo

回答

4

我可以很容易地只是做了查找和調用替換,以便它使用的snprintf或vsnprintf代替

不,它不是那麼容易的。請看snprintfvsnprintf的定義,您將看到它們帶有一個名爲size的額外參數,該參數指定輸出緩衝區的長度。這就是函數名稱中的n。爲了保證代碼安全,您必須查看您正在執行sprintf的每個位置,找出可以安全寫入輸出緩衝區的最大字節數,並將該數字作爲size參數傳遞給snprintfvsnprintf

不安全代碼:

char buffer[10]; 
sprintf(buffer, "%d %d", x, y); // UNSAFE if x and y can be large 

等效安全代碼:

char buffer[10]; 
snprintf(buffer, sizeof(buffer), "%d %d", x, y); 

也許如果所有的代碼符合上面的例子,那麼你可以做搜索和替換。但對於更復雜的情況,您可能需要考慮。

+2

當'buffer'是一個指針而不是一個數組時,search-and-replace將無法做正確的事情,但除非你使用小於指針大小的緩衝區(通常是4或8字節),否則只會導致您的輸出過度截斷而不允許溢出。希望這樣的截斷錯誤一旦運行測試就立即顯現出來。 –

相關問題