2017-08-25 14 views
2

我使用SonarQube和RATS (粗糙審計工具安全性)對我的嵌入式C代碼執行代碼分析。應特別注意確保分配在堆棧上的字符數組得到安全使用

Ubuntu下殼,我執行

rats --quiet --xml -w 1 . > ./rats_report.xml

得到將被導入到SonarQube報告。

我得到一些象這樣的錯誤:

Extra care should be taken to ensure that character arrays that are allocated on the stack are used safely. They are prime targets for buffer overflow attacks.

這是函數的代碼片段生成錯誤:

static char* GetQueryStringForValue(const char* valueLabel) 
{ 
    static char queryString[QUERY_LEN + 1]; 

    memcpy(queryString, '\0', sizeof(queryString)); 
    snprintf(queryString, sizeof(queryString), "{'%s'", valueLabel); 

    return queryString; 
} 

據我所知,這個問題是關係到分配到緩衝區堆棧。

我的問題是:哪種防止緩衝區溢出攻擊的最佳做法?

我應該添加特定的控件嗎?

感謝您的幫助!

BR, 費德里科

+3

'memcpy'?你在想'memset'嗎? 'memcpy'期待第二個參數的指針,而不是整數''\ 0''。 –

+3

奇怪'靜態字符查詢字符串[QUERY_LEN + 1];'*不*分配在堆棧上。 –

+0

在擔心安全性和靜態分析之前,請確保代碼實際編譯並給出預期的結果... – Lundin

回答

4

這是個假陽性,沒有被分配這裏的「堆棧」。使用static存儲類說明符,queryString靜態存儲持續時間這意味着它在您的程序的整個執行期間存在。沒有實施C會將這樣的對象放置在堆棧上。

但是這個功能還是非常錯誤的:

memcpy(queryString, '\0', sizeof(queryString)); 

這是試圖取消引用NULL指針(NUL字符常量被隱式轉換爲NULL指針)。你大概意思是

memset(queryString, 0, sizeof queryString); 

這就是說,如果你還是收到這樣的警告,把它當作它是什麼:一個警告。它警告你要格外小心。將代碼固定爲使用memset(),這裏無法溢出您的queryString


您的代碼有不同的幾分擔心:這不是線程安全,由於使用了static變量。讓主叫方提供queryString的緩衝區可能會更好。

+0

感謝Felix的解釋。所以初始化字符串的最好方法是使用memset和'0'值。我使用了memcpy,因爲,雖然如此,這樣我總是有一個帶終止符的字符串,如果我使用strcpy我的字符串是安全的,因爲我已經有了終止符。 – Federico

+0

@Federico初始化空字符串的最便宜的方法是將「0」寫入其第一個字節。 –

+2

@Federico:'snprintf()'終止你的'char'數組,所以你只需放下這個'mem *()'thingy即可。 – alk