【问题标题】:gcc memory allocation issue - buffer overflow attackgcc 内存分配问题 - 缓冲区溢出攻击
【发布时间】:2013-03-19 09:02:33
【问题描述】:

gcc 是否智能进行内存分配以防止缓冲区溢出攻击?

int function(char *str) {
    int a = 0;                 // See the
    char b[16] = "abcd";       // changes here

    if(!strcmp(b, str))
        a = 1;

    return a;
}

int function(char *str) {
    char b[16] = "abcd";       // See the
    int a = 0;                 // changes here

    if(!strcmp(b, str))
        a = 1;

    return a;
}

当我用 gdb 调试它时,它总是先分配内存给整数变量,然后是字符数组; 不管变量声明的顺序是什么。 即在上述两种情况下,编译器首先将内存分配给a,然后再分配给b

(higher address)
  Memory
|        |
|        |
+--------+
|        |
|        |
|        |
|        |
+--------+ <----- b (16 bytes)
|        |
+--------+ <----- a (4 bytes)
|        |
(lower address)

因此,即使我们在str 中提供超过16 个字符,它也不会影响a 的值。 有人可以帮我吗?

谢谢。

【问题讨论】:

  • 标准允许出于编译器想要完成的任何目的进行此类重新排序。最常见的 - 优化。它仍然是“智能”,但不是为了防止“缓冲区溢出攻击”。而且它仍然是一个未定义的行为(缓冲区溢出)

标签: c gcc


【解决方案1】:

是的,如果使用 -fstack-protector 标志运行。

当使用该标志运行时,GCC 添加堆栈金丝雀,将数组变量排序到堆栈帧的最高部分,以使其更难以溢出和破坏其他变量,并将函数参数的副本与其他当地人。

查看Wikipedia page on Buffer overflow protectionProPolice 主页了解更多信息

【讨论】:

  • @Ravi:一些发行版默认启用它。尝试使用-fno-stack-protector 进行编译,看看是否有所不同。
  • @MM.:已添加。为简洁起见,大部分都被忽略了。
  • 你是对的。 GCC 默认启用它。如果我们使用-fno-stack-protector 编译,它会按照声明的顺序顺序分配内存,而不是将数组变量分配到堆栈帧的最高部分。谢谢
【解决方案2】:

即使 GCC 有这样的功能来防止缓冲区溢出,这里还有许多其他考虑因素可能会导致固定的变量声明顺序。在哪里进行声明并不重要,编译器将根据变量在运行时的使用时间和方式做出分配决定。

最重要的是,编译器希望在堆栈帧中分配变量时考虑到最佳对齐方式。这可以根据 CPU 和优化设置以完全不同的方式进行。与优化内存消耗相比,优化速度可能会给出完全不同的分配。而且最有可能的是,它会将一些变量放入 CPU 寄存器中,从而消除整个 RAM 分配需求。

所以回答你的问题:GCC 以各种方式分配变量,具体取决于编译器端口。它是如何做到的,不是程序员需要过分关心的事情。可能有一些选项可以重新排列堆栈以防止缓冲区溢出攻击,但这仅在某些类型的应用程序中才有意义。据我们所知,特定系统甚至可能没有任何输入。所以编译器默认启用这个安全特性是没有意义的。

【讨论】:

    【解决方案3】:

    gcc 是否智能进行内存分配以防止缓冲区溢出攻击?

    不,它没有。如果没有边界检查,就无法防止攻击或缓冲区溢出,这并不总是可能的。您有时只能在事后检测到溢出。

    编译器最多可以在堆栈上的返回地址附近包含额外信息(所谓的canary value),然后在从函数返回之前检查它是否完好无损并且没有由于缓冲区溢出而被覆盖。

    【讨论】:

    • 这是错误的,GCC 可以并且确实重新排序变量以防止缓冲区溢出的影响
    • @Hasturkun 如果没有边界检查,您将无法防止溢出。您有时只能检测到一个。
    • 确实如此。但是你可以减轻它们,就像 ProPolice 等所做的那样。
    • @Hasturkun Prevention != 缓解。
    猜你喜欢
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 2019-04-14
    • 2021-12-03
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多