2015-11-13 4 views
-2

Следующие являются частью трех разных файлов .s. Файл .c был собран с тремя различными вариантами:Как этот код машины предотвращает переполнение буфера?

  1. -fno-рядный -fstack-протектор-сильный,
  2. -fno-рядный -fsanitize = адрес,
  3. -fno-рядный -fno -stack-protector -zexecstack.

Ниже приведены содержание .S файлов:

handle_read: 
.LFB20: 
    .cfi_startproc 
    pushq %r12 
    .cfi_def_cfa_offset 16 
    .cfi_offset 12, -16 
    pushq %rbp 
    .cfi_def_cfa_offset 24 
    .cfi_offset 6, -24 
    movq %rsi, %r12 
    pushq %rbx 
    .cfi_def_cfa_offset 32 
    .cfi_offset 3, -32 
    movq 8(%rdi), %rbx 
    movq %rdi, %rbp 
    movq 160(%rbx), %rsi 
    movq 152(%rbx), %rdx 
    cmpq %rdx, %rsi 
    jb  .L394 
    cmpq $5000, %rdx 
    jbe  .L421 

handle_read: 
.LASANPC20: 
.LFB20: 
    .cfi_startproc 
    pushq %r15 
    .cfi_def_cfa_offset 16 
    .cfi_offset 15, -16 
    pushq %r14 
    .cfi_def_cfa_offset 24 
    .cfi_offset 14, -24 
    pushq %r13 
    .cfi_def_cfa_offset 32 
    .cfi_offset 13, -32 
    pushq %r12 
    .cfi_def_cfa_offset 40 
    .cfi_offset 12, -40 
    pushq %rbp 
    .cfi_def_cfa_offset 48 
    .cfi_offset 6, -48 
    movq %rdi, %rbp 
    addq $8, %rdi 
    pushq %rbx 
    .cfi_def_cfa_offset 56 
    .cfi_offset 3, -56 
    movq %rdi, %rax 
    shrq $3, %rax 
    subq $24, %rsp 
    .cfi_def_cfa_offset 80 
    cmpb $0, 2147450880(%rax) 
    jne  .L1170 
    movq 8(%rbp), %rbx 
    leaq 160(%rbx), %r13 
    movq %r13, %r15 
    shrq $3, %r15 
    cmpb $0, 2147450880(%r15) 
    jne  .L1171 
    leaq 152(%rbx), %r14 
    movq %rsi, %r12 
    movq 160(%rbx), %rsi 
    movq %r14, %rax 
    shrq $3, %rax 
    cmpb $0, 2147450880(%rax) 
    jne  .L1172 
    movq 152(%rbx), %rdx 
    leaq 144(%rbx), %rcx 
    cmpq %rdx, %rsi 
    jb  .L1054 
    cmpq $5000, %rdx 
    jbe  .L1055 
    movl $httpd_err400form, %eax 
    shrq $3, %rax 
    cmpb $0, 2147450880(%rax) 
    jne  .L1173 
    movl $httpd_err400title, %eax 
    movq httpd_err400form(%rip), %r8 
    shrq $3, %rax 
    cmpb $0, 2147450880(%rax) 
    jne  .L1174 


handle_read: 
.LFB20: 
    .cfi_startproc 
    pushq %r12 
    .cfi_def_cfa_offset 16 
    .cfi_offset 12, -16 
    pushq %rbp 
    .cfi_def_cfa_offset 24 
    .cfi_offset 6, -24 
    movq %rsi, %r12 
    pushq %rbx 
    .cfi_def_cfa_offset 32 
    .cfi_offset 3, -32 
    movq 8(%rdi), %rbx 
    movq %rdi, %rbp 
    movq 160(%rbx), %rsi 
    movq 152(%rbx), %rdx 
    cmpq %rdx, %rsi 
    jb  .L384 
    cmpq $5000, %rdx 
    jbe  .L411 

Может кто-нибудь сказать мне, как эти коды предотвратить переполнение буфера?

+0

Взгляните на документацию по каждому из вариантов, это поможет вам понять, что делается в каждом случае. 'fstack-protector-strong': https://lwn.net/Articles/584225/. Вы можете использовать Google другие. – EkcenierK

+2

Учитывая, что первая и третья функции одинаковы, я бы сказал, что здесь что-то странно. Кроме того, у функции нет типа доступа, который вызывает переполнение буфера. Я бы сказал: ** Опубликовать целые функции, а не только их часть ** – EOF

ответ

2

Функция handle_read не в конечном итоге выделяет что-либо в стеке, поэтому нет ничего для -fstack-protector-strong для защиты, и поэтому этот параметр не имеет значения. Опция -zexecstack устанавливает флаг в сгенерированном исполняемом файле, сообщая операционной системе, что он должен разрешить выполнение кода, хранящегося в стеке. Он не влияет на сгенерированную сборку.

Только опция -fsanitize=address имеет эффект, который отображается в сгенерированном сборке, который вы опубликовали. Он отвечает за последовательности shrq $3, rXX; cmp $0, 2147450880(%rXX); jne .LXXXX, которые появляются во втором блоке сгенерированной сборки. Эти инструкции ищут каждый адрес в памяти, к которому обращается функция в таблице «теневая память». В таблице записаны, какие местоположения были выделены, а какие нет. Если вставленный код обнаруживает, что программа пытается получить доступ к ячейке памяти, которая еще не была выделена, это вызовет выход программы с сообщением об ошибке.

Для получения более подробной информации о работе таблицы памяти тени и о том, как работает AddressSanitizer, вы можете прочитать статью Usenix автора AddressSanitizer: A Fast Address Sanity Checker.

Смежные вопросы