gcc -fno-stack-protector option

3

我正在做一个学校项目,主要是想了解堆栈溢出的知识。我正在处理的一些示例代码如下(已经简化):

char test[10];
int i;
for (i=0;i < 10000;i++) {
    test[i] = 'a';
}

当我使用gcc编译时,一切都很顺利。gcc会自动保护堆栈,永远不会让它溢出。现在,如果我尝试使用gcc -fno-stack-protector,同样的程序也可以运行。我甚至对汇编文件进行了比较(使用-S选项),它们是相同的。这是怎么回事?我查看了man页面,没有提到-fno-stack选项...所有在线资料都指向-fno-stack-protector选项,但我根本无法再现任何东西...
谢谢您的帮助。 :)
1个回答

3

你确定吗?我的输出结果是(如果未禁用堆栈保护):

.L2:
        cmpl    $9999, -36(%rbp)
        jle     .L3
        movq    -8(%rbp), %rdx
        xorq    %fs:40, %rdx
        je      .L5
        call    __stack_chk_fail

来源

int test() {
char test[10];
int i;
for (i=0;i < 10000;i++) {
  test[i] = 'a';
 }
}

3
嗯嗯嗯,我正在研究这个问题,奇怪的是默认情况下未启用栈保护,因此-fno-stack-protector选项完全没有作用。我必须使用-fstack-protector选项来启用栈保护,但现在运行我的应用程序会导致段错误。因此,栈保护会导致应用程序抛出分段错误,而没有栈保护则允许代码随意修改堆栈。 - Glen Takahashi
根据系统(发行版)的不同,最好的做法是“除非你设置了它,否则什么都没有被设置”。此外,一些优化标志会将其关闭(-O3,不认为O2会这样做)。 - Tomas Pruzina
5
@Glen,你的程序能够顺利运行是个巧合,可能比段错误还糟糕。在禁用栈保护的情况下,它正在愉快地超出数组的边界进行写操作,只是因为没有检查是否越界,所以你并不知道(你没有调用printf函数)。它可能已经用delete_hard_drive或launch_the_missiles来覆盖printf的地址,而你只是不知道。通常,大声的崩溃比默默失败要好。 - David Stone
所以为了确保它开启了 -fstack-protector,是吗? - rogerdpack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接