【问题标题】:Is this really a buffer overflow?这真的是缓冲区溢出吗?
【发布时间】:2009-02-16 15:36:48
【问题描述】:

我们使用的静态分析工具将类似于以下的 C 代码标记为严重缓冲区溢出。

#define size 64
char  buf [size + 1] = "";
memset (buf, 0, size + 1);

工具的错误信息是:Buffer Overflow (Array Index Out of Bounds): The array 'buf' size is 1. Array 'buf' may use the 0..64 index.

这是合法的吗?将字符数组赋值给空字符串真的会导致它的长度减少到一个字节,就好像它被定义为char buf [] = "";

【问题讨论】:

  • 显然它会在 C99 中出现。我的错。 :)
  • 你应该从size的定义中删除分号。

标签: c static-analysis buffer-overflow string-literals


【解决方案1】:

除了 char buf[size+1] 因为 size 是运行时值而无法编译这一事实之外,假设您可以将 buf 构建为大小为 65 的数组,那么 memset(buf, 0, 65) 将不是溢出。

你的工具很可能被你的语法问题弄糊涂了。

[编辑:更多信息]

根据我原来的帖子的 cmets,我建议如下:

#define size 64
char buf[size+1];
strcpy(buf, "");
memset(buf, 0, size+1);

我相信 Rob Kennedy 是正确的;您的工具使用空字符串初始值设定项作为数组大小,而不是静态数组声明。

【讨论】:

  • C99 具有动态大小的数组。
  • 真的吗?好吧,让我退出游戏。显然我已经很久没有做过 C 了。
  • 它不能编译的原因是你不能初始化一个动态大小的数组。动态大小的数组已经允许使用将近 10 年了。
  • 也就是说,该工具可能没有意识到这一点。它可以使用初始化器来确定数组的大小。
  • 对 strcpy 的调用是多余的; memset 无论如何都会覆盖(空)字符串。
【解决方案2】:

将 "" 分配给 buf[size+1] 不会重置 buf 的大小,但它没有意义,因为它复制了后续 memset 所做的一小部分(并且它混淆了您的静态分析工具 - 您可能想要针对它提交错误报告)。

【讨论】:

    【解决方案3】:

    这不是缓冲区溢出。

    这可能是一种更清洁的方法。 当然它需要更少的代码行数。

    #define size 64
    char buf[size + 1] = {0};
    

    【讨论】:

      【解决方案4】:

      这是合法的 - 缓冲区足够大。该工具警告您 size_t 可能大于 int 并且尝试将其用作索引器可能会导致不可预测的结果。

      【讨论】:

      • 我不认为这是该工具所警告的。它清楚地表明数组大小为 1,并且正在使用索引 0 到 64。它不是在抱怨整数的大小。
      • 修改示例以避免将来与 size_t 混淆。
      • 好吧,该工具显示出对不正确的数组大小的偏执。这可能只是工具中的一个错误——工具的来源可以确定。然而 size_t 的问题是一个众所周知的问题,在某些情况下它会很痛苦,尤其是在移植到 64 位平台时。
      猜你喜欢
      • 2010-10-03
      • 1970-01-01
      • 2015-12-16
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 2013-08-31
      • 2013-02-17
      • 2013-11-06
      相关资源
      最近更新 更多