gcc内存分配问题 - 缓冲区溢出攻击

时间:2013-03-19 09:02:34

标签: c gcc

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的值。 有人可以帮帮我吗?

谢谢。

3 个答案:

答案 0 :(得分:11)

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

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

有关详细信息,请参阅Wikipedia page on Buffer overflow protectionProPolice主页

答案 1 :(得分:2)

即使GCC具有防止缓冲区溢出的功能,此处还有许多其他注意事项可能会导致固定的变量声明顺序。如果声明不是很重要,编译器将根据变量在运行时使用的时间和方式来做出分配决策。

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

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

答案 2 :(得分:-1)

  

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

不,它没有。无法在没有边界检查的情况下阻止攻击或缓冲区溢出,这并非总是可行。事后,您有时只能检测到溢出。

编译器最多可以在堆栈的返回地址附近包含额外的信息(所谓的canary value),并且在从函数返回之前检查它是否完整,并且不会因缓冲区溢出而被覆盖。 / p>