обнаружение переполнения стека и кучи - PullRequest
7 голосов
/ 14 августа 2011

В системе с постраничным спросом, такой как linux, где страницы могут быть ~ 4k от того, что я прочитал, это обеспечивает защиту, проверяя, превышает ли размер стека или кучи количество страниц, предоставляемых каждой.Когда я создаю две переменные

char *s = (char *) malloc(100);   
char sa[100];

В цикле for я могу написать s[i] = 'c'; почти 4000 раз, прежде чем произойдет ошибка памяти, тогда как с sa[i] = 'c'; EDIT: я получу segmentation fault или stack smashing ошибка для чего-либо большего, чем размер массива.

Я могу понять, что в первом случае происходит сбой страницы, и он видит, что больше не было выделено страниц для кучи, а значит, и нарушение памяти.Но что происходит во втором случае, когда gcc выполняет проверку во время выполнения для всех предварительно выделенных переменных?.
РЕДАКТИРОВАТЬ: я публикую весь код ниже

int main(int argc,char* argv[]){
char *s = (char *) malloc(20);
char sa[400] = {0};
int i ,count;
printf(" enter the number of chars to write: ");
scanf("%d",&count);
for (i=0;i<count;i++){
printf("%d\n",i);
sa[i] = 'a';
//s[i] = 'a';
}
free(s);

}

1 Ответ

2 голосов
/ 14 августа 2011

Во многих 32-битных операционных системах стек растет вниз. Вы используете только положительные индексы в массиве, так что это зависит от того, насколько глубоко вложен вызов вашей функции. По мере индексации массива вы сначала перезапишете канарейку. Таким образом, ошибка разрушения стека является первой. Далее вы начнете перезаписывать аргументы функции и возвращать адрес. Без канарейки это приведет к тому, что функция return никогда не попадет в землю, что обычно приводит к segfault. Не всегда, это может случайно привести к допустимому коду, логике атак переполнения стекового буфера.

По мере продолжения вы в конечном итоге будете писать за вершиной стека на нераспределенных страницах. Segfault тогда. В небольшой тестовой программе с несколькими вложенными вызовами, которая происходит быстро, несколько килобайт дают или берут.

Также попробуйте с отрицательными смещениями. Это может продолжаться некоторое время, не вызывая каких-либо ошибок, поскольку вы записываете в нераспределенное пространство стека. Сегфоут возникает, когда вы пишете больше выделенного размера стека, обычно мегабайта. В Windows вы вызываете страницу защиты стека, генерируя исключение, для которого этот сайт называется.

...