cppcheck : 缓冲区被越界访问

Posted

技术标签:

【中文标题】cppcheck : 缓冲区被越界访问【英文标题】:cppcheck : Buffer is accessed out of bounds 【发布时间】:2020-01-27 22:27:55 【问题描述】:

我有下面的代码。运行cppcheck工具后报错Buffer is access out of bounds?用snprintf在线报错。

#include <stdio.h>

int main(int argc, char * argv[])

    if (argc > 1) 
        char testref[8] = "";
        snprintf(testref, sizeof(testref), "Ref:%s", argv[1]);
        printf("===>testref=%s\n", testref);
    

命令行交互下方:

amin@ubuntu:$ gcc test.c -o test
amin@ubuntu:$ 
amin@ubuntu:$ ./test hello_world
===>testref=Ref:hel
amin@ubuntu:$ cppcheck test.c 
Checking test.c...
[test.c:7]: (error) Buffer is accessed out of bounds.
amin@ubuntu:$

cppcheck 报告这个错误是否正确?

【问题讨论】:

argv[1] 中的值如果长度超过 3 个字节,将被截断,但代码没有我能看到的其他问题。错误报告可能是合适的——或者,至少,在cppcheck 中询问为什么它不是错误。 您使用的是哪个版本的 cppcheck?使用 Cppcheck 1.82 我没有收到任何错误代码。 如果 snprintf() 返回 -1,那么 printf("===&gt;testref=%s\n", testref);不是是件好事。为了完整性。按照@wildplasser 的建议报告snprintf() 的返回值 @wildplasser,手册页确实非常有用,但您认为这对解决这个特定问题有何帮助? (如果您认为自己有解决方案,请考虑发布答案。) @wildplasser,我已经搜索了有关此的文档,但找不到。当前的手册页指的是 AFAIK 不会发生缓冲区溢出的“正确”行为。在最初的 ANSI 标准中,snprintf() 函数不存在。我将不胜感激您提到的功能的参考。这确实可以解释观察到的问题。 【参考方案1】:

我认为,一般来说,cppcheck 报这个错误是正确的。 snprintf 函数的行为取决于实现,并且在某些实现中,如果字符串对于缓冲区来说太大,则不能保证写入空字符。在这种情况下,对printf() 的连续调用将读取缓冲区边界之外的内容。

我至少可以找到 one example 的 snprintf 实现,这会导致您的代码出现越界错误。根据this comment,c99 之前的 True64/DigitalUnix 也是如此。

看看cppcheck是否也报告以下代码的错误会很有趣(它不应该报告错误):

#include <stdio.h>

int main(int argc, char * argv[])

    if (argc > 1) 
        char testref[8] = "";
        int ret = snprintf(testref, sizeof(testref), "Ref:%s", argv[1]);
        if (ret >= 0) 
            printf("===>testref=%s\n", testref);
        
    

另请注意,Cppcheck 1.82 版不会为您的代码报告错误。我不确定为什么 1.72 版会报告错误而 1.82 版不会。

【讨论】:

snprintf() 是由 c 标准定义的,cppcheck 应该考虑这些语义。因此,我会说新版本 1.82 的行为正确。 @Ctx,没有“C 标准”之类的东西 ;-) 在最初的 ANSI 标准中,这个功能不存在。在 C99 中似乎定义明确,但还有许多其他标准和实现。我不确定应该考虑哪个标准 cppcheck。 cppcheck 确实可以选择传递它应该检查的标准。如果您将-std=c99 标志传递给它,我希望它会使用snprintf 的c99 版本。

以上是关于cppcheck : 缓冲区被越界访问的主要内容,如果未能解决你的问题,请参考以下文章

缓冲区在 cppcheck 中被越界访问

cppcheck 报告“缓冲区访问越界”

多图详解缓冲区溢出问题

对缓冲区大小施加限制

内存溢出内存泄露内存越界缓冲区溢出栈溢出

内存溢出内存泄露内存越界缓冲区溢出栈溢出