2012-06-15 3 views
1

Прочитал какой-то текст и играл с попыткой записать за размером массива в переполнение буфера C i.e. Текст указывает, что всякий раз, когда вы пытаетесь написать, чтобы сказать array[5], когда длина массива равна 5, вы получаете ошибку сегментации, но я, похоже, не получаю этого, используя код ниже. Код действительно работает.Переполнение буфера на Mac OSX?

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    int i; 
    int array[5] = {1, 2, 3, 4, 5}; 
    for (i = 0; i <= 255; i++) 
    { 
     array[i] = 10; 
    } 
    int len = sizeof(array)/sizeof(int); 
    printf("%d\n", len); 
    printf("%d\n", array[254]); 
} 

Об исполнении последнего утверждения, 10 печатается. Интересно, является ли это уязвимостью или если что-то мне не хватает. Я запускаю код из iterm2 на macbook pro.

+0

Это может иметь какое-то отношение к направлению роста памяти в стеке и его отношению к направлению, в котором процессор перемещается по памяти при последовательном индексировании массива. На x86 стек растет, и процессор поднимается вверх по стеку, поэтому вы можете перезаписать обратный адрес вызывающей функции. – AlexWebr

ответ

4

Запись в конце - это неопределенное поведение - все может случиться.

+1

не означает, что кто-то может изменить другой процесс? – cobie

+1

@cobie: Что касается языка C, ** да **. ОС может пообещать, что этого не произойдет, но это ОС, обеспечивающая ее, а не язык. Конечно, это означает, что ваше приложение теоретически может модифицировать память другого процесса в некоторых ОС (хотя на практике переполнение на 1 байт, вероятно, не повлияет на память другого процесса). – Brian

+0

@cobie: Абсолютно нет - какая часть «Поведение не определено». вы не понимаете ...... – mattnz

0

Вы сможете изучить любую память, принадлежащую вашему текущему процессу. Когда вы попадаете в конец этого блока памяти, вы получите ошибку EXC_BAD_ACCESS. Попробуйте эту исправленную версию кода, петлями, пока ОС не убивает его:

#include <stdio.h> 
#include <string.h> 

int main(int argc, const char * argv[]) 
{ 
    int i = 0; 
    int array[5] = {1, 2, 3, 4, 5}; 
    while (1) 
    { 
     printf("%llu - %d\n", i, array[i]); 
      // if (&i == &array[i]) printf("Overwriting i\n"); 
      // array[i] = 2; 
     ++i; 
    } 
} 

Если раскомментировать закомментированные строки, вы обнаружите, что вы застряли в бесконечном цикле между я значениями 3 и 6. Вы» перезаписывая память, расположенную по адресу целого числа i.

1

Вы записываете данные за конец массива. Это неопределенное поведение. Неопределенное поведение означает, что он может работать в пятницу, но падает в субботу.

Вот C параграф, который говорит, что это неопределенное поведение:

(C99, 6.5.3.2p4) Если недопустимое значение присваивается указателю, поведение унарного оператора * не определено ,

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