海湾合作委员会是否会产生金丝雀?

zon*_*uwu 11 c compiler-construction assembly gcc buffer-overflow

我的gcc版本是4.8.2,操作系统是ubuntu 14.04(64位).我发现有时gcc自动生成金丝雀有时候不做缓冲区溢出保护,为什么?

生成金丝雀的情况:当SIZE是四的倍数时

#include<stdio.h>
#define SIZE 4

int main()
{
    char s[SIZE];
    scanf("%s", s);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

asm在gcc -c -g -Wa,-a,-ad之后

...
   4:a.c           **** int main()
   5:a.c           **** {
  13                    .loc 1 5 0
  14                    .cfi_startproc
  15 0000 55            pushq   %rbp
  16                    .cfi_def_cfa_offset 16
  17                    .cfi_offset 6, -16
  18 0001 4889E5        movq    %rsp, %rbp
  19                    .cfi_def_cfa_register 6
  20 0004 4883EC10      subq    $16, %rsp
  21                    .loc 1 5 0
  22 0008 64488B04      movq    %fs:40, %rax
  22      25280000 
  22      00
  23 0011 488945F8      movq    %rax, -8(%rbp)
  24 0015 31C0          xorl    %eax, %eax
   6:a.c           ****     char s[SIZE];
   7:a.c           ****     scanf("%s", s);
...
Run Code Online (Sandbox Code Playgroud)

不产生金丝雀的情况:不是四个的倍数

#include<stdio.h>
#define SIZE 2

int main()
{
    char s[SIZE];
    scanf("%s", s);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

asm在gcc -c -g -Wa,-a,-ad之后

...
   4:a.c           **** int main()
   5:a.c           **** {
  13                    .loc 1 5 0
  14                    .cfi_startproc
  15 0000 55            pushq   %rbp
  16                    .cfi_def_cfa_offset 16
  17                    .cfi_offset 6, -16
  18 0001 4889E5        movq    %rsp, %rbp
  19                    .cfi_def_cfa_register 6
  20 0004 4883EC10      subq    $16, %rsp
   6:a.c           ****     char s[SIZE];
   7:a.c           ****     scanf("%s", s);
...
Run Code Online (Sandbox Code Playgroud)

xai*_*zek 14

好的,我想我们知道评论的答案,所以我会在这里发布,明确说明.

将金丝雀放入许多功能可能会导致性能下降.这就是为什么有几种方法可以告诉GCC我们想使用它们,这是很好的描述在这里.主要观点:

  1. 默认情况下不使用Canaries,需要传递启用它们的标志之一.
  2. 为了节省执行时间,GCC使用带-fstack-protector标志的简单启发式:为使用alloca大于8字节的本地缓冲区的函数添加canaries (默认情况下).
  3. 可以使用ssp-buffer-size参数调整启发式:--param ssp-buffer-size=4.

显然Ubuntu发布了缓冲区大小改变为GCC的版本4,因此缓冲区不会触发生成金丝雀.我确认(并且其他任何人都应该能够重复)通过编译两个示例--param ssp-buffer-size=4,它们只为其中一个产生带有金丝雀的程序集.