2014-06-28 13 views
10

Phiên bản gcc của tôi là 4.8.2 và hệ điều hành là ubuntu 14.04 (64 bit). Tôi thấy rằng đôi khi gcc tự động tạo ra các canary để làm bộ đệm tràn bảo vệ đôi khi không, tại sao?GCC có tạo Canary hay không?

trường hợp để tạo canary: khi SIZE là nhiều bốn

#include<stdio.h> 
#define SIZE 4 

int main() 
{ 
    char s[SIZE]; 
    scanf("%s", s); 
    return 0; 
} 

asm sau 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); 
... 

trường hợp không để tạo ra chim hoàng yến: không phải là bội số của bốn

#include<stdio.h> 
#define SIZE 2 

int main() 
{ 
    char s[SIZE]; 
    scanf("%s", s); 
    return 0; 
} 

asm sau 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); 
... 
+2

Hệ điều hành của bạn (cả tên và phiên bản) là gì? Điều quan trọng là vì các bản phân phối khác nhau bao gồm các bản vá lỗi khác nhau và cờ mặc định ([xem] (https://en.wikipedia.org/wiki/Stack-smashing_protection#GNU_Compiler_Collection_.28GCC.29)). Ví dụ, canaries không được tạo ra cho tôi trừ khi tôi chỉ định '-fstack-protector'. – xaizek

+0

Hệ điều hành của tôi là Ubuntu 14.04 64bit – zongyuwu

+1

Sau đó, '-fstack-protector' có thể được sử dụng, nhưng trang man nói rằng canary được tạo cho tất cả các hàm có bộ đệm lớn hơn 8 byte và trình biên dịch cấp 16 byte cho cả hai bộ đệm (giống nhau máy của bạn và của tôi), vì vậy cả hai phiên bản nên có nó. Tôi nhận được hành vi khác nhau trên cùng một phiên bản của GCC. Bạn đã thử số lớn hơn, ví dụ: 17 và 20? – xaizek

Trả lời

10

OK, tôi đoán chúng tôi biết câu trả lời từ nhận xét, vì vậy tôi sẽ đăng câu trả lời ở đây để nêu rõ.

Đưa canaries vào nhiều chức năng có thể dẫn đến suy giảm hiệu suất. Đó là lý do tại sao có một số cách để nói với GCC chúng tôi muốn sử dụng chúng, được mô tả rõ ràng here. Ý tưởng chính:

  1. Canaries không được sử dụng theo mặc định, người ta cần phải vượt qua một trong những cờ cho phép họ.
  2. Để tiết kiệm thời gian thực hiện, GCC sử dụng heuristic đơn giản với cờ -fstack-protector: thêm canaries cho các hàm sử dụng alloca hoặc bộ đệm cục bộ lớn hơn 8 byte (theo mặc định).
  3. Các heuristic có thể được tinh chỉnh với tham số ssp-buffer-size: --param ssp-buffer-size=4.

Rõ ràng Ubuntu gửi phiên bản GCC với kích thước bộ đệm đã thay đổi thành 4, do đó bộ đệm ít hơn không kích hoạt thế hệ của một con chim hoàng yến. Tôi xác nhận (và bất kỳ ai khác có thể lặp lại) rằng bằng cách biên soạn hai ví dụ với --param ssp-buffer-size=4, trong đó sản xuất lắp ráp với canaries cho chỉ một trong số họ.

Các vấn đề liên quan