Является ли задачей программного обеспечения (операционной системы) обнаружение переполнения стека или аппаратное переполнение стека, вызывающее исключение в ЦП?
Является ли задачей программного обеспечения (операционной системы) обнаружение переполнения стека или аппаратное переполнение стека, вызывающее исключение в ЦП?
Ответы:
Это может быть программное или аппаратное обеспечение, или и то, и другое.
Существует два вида переполнений: переполнение при увеличении стека (при входе в функцию) и переполнение при доступе к массиву в стеке. Переполнения при наращивании стека можно обнаружить, выполнив проверку границ при входе в функцию, чтобы убедиться, что места достаточно (и либо сигнализировать об ошибке, либо увеличить стек, если его нет). Переполнения при доступе к массиву в стеке являются проблемой только в языках низкого уровня, которые не проверяют границы массива; решение - проверить границы массива.
Преимущество этих программных подходов в том, что они работают полностью надежно: вы можете быть уверены, что будет обнаружено любое переполнение стека. Их недостатком является то, что они увеличивают размер кода и время выполнения. Аппаратное обеспечение может помочь, предоставляя метод для обнаружения большинства переполнений без затрат, пока переполнение не происходит. В архитектуре с MMU environment среда выполнения может организовать отображение стека на границе страницы, при этом следующая страница остается не отображенной.
+---------------+---------------+---------------+---------------+
| stack | unmapped | other stuff |
| ----> direction of growth | | |
+---------------+---------------+---------------+---------------+
^ ^ ^ ^ ^ page boundaries
Таким образом, если программное обеспечение пытается получить доступ к данным за пределами страницы (будь то из-за того, что указатель стека перешел за границы или из-за того, что доступ к массиву выходит за границы и за границы), это вызовет ошибку, получив доступ к не отображенной области , Это происходит только в том случае, если переполнение достаточно мало: если величина переполнения слишком велика, программа может в конечном итоге получить доступ к другим данным на другой стороне промежутка в адресном пространстве.
Недостатками аппаратного подхода является то, что он не является полностью надежным, поскольку переполнение большого объема может не обнаруживаться, и что он не обнаруживает переполнения массива, которые остаются в адресуемом пространстве.
Чтобы обнаружить переполнение массива, канарейкой является еще один программный метод : поместите специальное значение в верхнюю часть стека или между кадрами и убедитесь, что значение канарейки не изменилось при возврате функции. Это также несовершенный метод, поскольку переполнение может полностью исключить канарейку или может не быть обнаружено, потому что канарейка была восстановлена к моменту ее проверки. Тем не менее полезно усложнить использование некоторых уязвимостей безопасности.
Самый безопасный и дешевый способ избежать переполнения стека - это вычислить объем стека, который понадобится программе перед началом его выполнения, путем статического анализа. Однако это не всегда практично: объем стека, необходимый программе, в общем, неразрешим, и зависит от данных, которыми манипулирует программа.
¹ Тот же принцип можно применять только с MPU или без защиты памяти, если существует один поток, стек которого находится на границе существующих физических отображений.