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

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

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

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

segmentation fault: 11

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

gets()示例

#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;

}

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

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

这对于gets()或fgets()都是有效的,任何结果都是可能的:

  • No visible affect what-so-ever
  • Immediate program termination (a crash)
  • Termination at a later point in the programs life time (maybe 1 second later, maybe 15 days later)
  • Termination of another, unrelated program
  • Incorrect program behaviour and/or calculation … and the list goes on. This is the problem with “buffer overflow” bugs, you just can’t
    tell when and how they’ll bite you.

你可以阅读更多here.但是如果你有许多嵌套调用另一个函数(比如你的第一种情况),那么粉碎堆栈的几率会增加.

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

点赞