GCC генерирует Canary или нет?
Моя версия 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;
}
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);
...
случай не создавать канарейку: не кратное четырем
#include<stdio.h>
#define SIZE 2
int main()
{
char s[SIZE];
scanf("%s", s);
return 0;
}
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);
...
Ответы
Ответ 1
ОК, я думаю, мы знаем ответ из комментариев, поэтому я отправлю его здесь, чтобы указать его явно.
Включение канарейки во множество функций может привести к ухудшению производительности. Вот почему есть несколько способов сказать GCC, что мы хотим их использовать, которые описаны здесь здесь. Основные идеи:
- Канары не используются по умолчанию, нужно передать один из флагов, которые их активируют.
- Чтобы сохранить время выполнения, GCC использует простую эвристику с флагом
-fstack-protector
: добавляет канавари для функций, которые используют alloca
или локальные буферы, превышающие 8
байты (по умолчанию).
- Эвристика может быть изменена с помощью параметра
ssp-buffer-size
: --param ssp-buffer-size=4
.
Очевидно, Ubuntu отправляет версию GCC с размером буфера, измененным на 4
, поэтому буферы меньше, чем это не вызывает генерацию канарейки. Я подтверждаю (и кто-то еще должен повторять), что, компилируя два примера с --param ssp-buffer-size=4
, который создает сборку с канареями только для одного из них.