Почему массивы не растут в направлении стека при использовании в функциях в качестве локальных переменных? - PullRequest
6 голосов
/ 06 ноября 2019

Это может быть глупый вопрос, но мне было интересно, что, если массив был заполнен значениями таким образом, чтобы он рос в направлении стека (так что в случае массива единственная локальная переменная такая, что перваяэлемент массива адресуется на один байт после указателя стекового кадра / базового указателя, второй элемент - через два байта после указателя стекового кадра / базового указателя, ...), не сделает ли это переполнение стека в C намного более безопасным, так как обратный адрес не можеттак просто перезаписать (массив должен был бы заполнить почти всю оперативную память и, таким образом, программа могла бы аварийно завершить работу вместо выполнения какого-либо вредоносного кода)?

Ответы [ 2 ]

4 голосов
/ 06 ноября 2019

Вы не можете сделать это со стеком, который растет без полной замены модели адресации для всех массивов. Это жизнеспособный вариант реализации, но он не совместим с существующими ABI.

Что вы заметили, так это то, что в некотором смысле наличие растущего стека (где вверх - направление положительного индекса массива) в некоторыхспособы безопаснее, чем стек, который растет. Тем не менее, это не намного безопаснее. Подумайте, что происходит, когда вы передаете адрес массива с автоматическим хранением другой функции. Вызываемый объект будет отображаться в стеке выше, чем массив, поэтому любое переполнение массива будет перетекать в кадр стека вызываемого, возможно, включая его адрес возврата. Например:

void foo()
{
    char s[4];
    strcpy(s, "hello world");
}

Когда возвращается strcpy, его адрес возврата, возможно, был забит путем сохранения за концом массива, адрес которого был ему передан.

2 голосов
/ 06 ноября 2019

«Направление стека» является функцией реализации, а не языка - спецификация языка даже не предполагает наличия стека.

Индексирование массивов работает путем добавления неотрицательного смещения к базовому адресу и разыменования результата - массивы всегда должны увеличиваться в сторону увеличения адресов, независимо от направления роста стека.

Единственное, что действительно сделает операции с массивами безопасными (r), - это для спецификации языка C требуется проверка границ для всех обращений к массиву и создание исключения для внешнего доступа. ограничивает доступ. Конечно, спецификация языка C также должна была бы добавить структурированную обработку исключений (текущий метод обработки сигналов был бы крайне неадекватным).

Такое дополнение ... маловероятно .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...