2017-08-25 13 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