堆栈保护程序适用于strcpy()示例,但不适用于gets()示例

时间:2015-06-29 15:40:05

标签: c security gcc

我正在测试GCC堆栈保护器。当我使用不安全的strcpy()函数溢出缓冲区时,堆栈保护程序检测到我正在做的事情并引发以下异常:

*** stack smashing detected ***: ./a.out terminated
Aborted (core dumped)

当我使用不安全的gets()函数做同样的事情时,我得到了一个分段错误。

segmentation fault: 11

为什么会这样?这两种情况有什么区别?这是我一直在使用的示例代码

获取()示例

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>

void say_hello (void);

int main (){

        printf("Enter your name\n");
        say_hello();
        return 0;
}

void say_hello (void) {

        char name[5];
        gets(name); //this is a unsafe function to use. Results in stack overflow
        printf("Hello %s\n", name);

}

strcpy()示例

#include <stdio.h>
#include <string.h>

int main(int argc, char** argv){

        char buffer [5];
        strcpy(buffer,argv[1]);


 return 0;

}

1 个答案:

答案 0 :(得分:2)

根据文档,strcpy()可能导致溢出错误,因为没有检查数据在新数组中的适合位置。这种溢出的结果可能有时从未被注意到,这完全取决于数据的写入位置。但是,常见的结果是堆和/或内存损坏。

strcpy()的一个安全替代方法是strcpy_s()的使用,它也需要数组的大小。

同样适用于gets()fgets(),任何结果都是可能的:

  
      
  • 没有明显的影响,所以
  •   
  • 立即终止程序(崩溃)
  •   
  • 在节目生命时间的晚些时候终止(可能是1秒后,也许是15天后)
  •   
  • 终止另一个不相关的计划
  •   
  • 程序行为和/或计算不正确......列表继续。这是“缓冲区溢出”错误的问题,你就是不能   告诉他们什么时候以及如何咬你。
  •   

您可以阅读更多here。但是,如果您对其他函数进行了多次嵌套调用(例如在第一种情况下),那么粉碎堆栈的几率会增加。

总而言之,在你的情况下恰好是这样,因为当发生溢出时它们的未定义行为。