Ответ 1
Переполнение стека
void stack_overflow(const char *x)
{
char y[3];
strcpy(y, x);
}
Переполнение кучи
void heap_overflow(const char *x)
{
char *y = malloc(strlen(x));
strcpy(y, x);
}
Анализ
Обе функции попираются за выделенное пространство.
Если вы вызываете stack_overflow("abc")
, он копирует 4 символа (включая нуль) в пространство, выделенное для 3 символов. Что происходит после этого, зависит от того, где был нанесен ущерб. Переменная y
находится в стеке, поэтому это переполнение стека.
Независимо от того, как вы вызываете heap_overflow()
, он запрашивает слишком мало байтов из кучи, а затем пишет за его пределами. Что коварно в том, что некоторое время - даже большую часть времени - похоже, будет работать, потому что система кучи выделяет больше места, чем вы запрашиваете. Однако вы можете попирать контрольные данные, а затем все ставки отключены.
Переполнение кучи очень мало и трудно обнаружить. Переполнение стека может быть небольшим (не существует, если переданная строка достаточно коротка) или драматична. Вы обычно получаете более драматические эффекты, когда пишете дальше за выделенным пространством, но любая запись за пределами выделенного пространства приводит к поведению undefined - все может случиться.
Вы гарантируете, что нет проблем, зная, насколько большой объект, который вы копируете, и сколько места для его получения, и убедитесь, что вы не копируете больше материала, чем есть место. Всегда, каждый раз.