ТЕХНИКА ОПТИМИЗАЦИИ ПРОГРАММ

       

Как с ними борются?


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

Очевидное "лобовое" решение проблемы заключается в синтаксической проверке выхода за границы массива при каждом обращении к нему. Такие проверки опционально реализованы в некоторых компиляторах Си, например, в компиляторе "Compaq C" для Tru64 Unix и Alpha Linux. Они не предотвращают возможности переполнения вообще и обеспечивают лишь контроль непосредственных ссылок на элементы массивов, но бессильны предсказать значение указателей.

Проверка корректности указателей вообще не может быть реализована синтаксически, а осуществима только на машинном уровне. "Bounds Checker" – специальное дополнение для компилятора gcc – именно так и поступает, гарантированно исключая всякую возможность переполнения. Платой за надежность становится значительное, доходящее до тридцати

(!) и более раз падение производительности программы. В большинстве случаев это не приемлемо, поэтому, такой подход не сыскал популярности и практически никем не применяется. "Bounds Checker" хорошо подходит (и широко используется!) для облегчения отладки приложений, но вовсе не факт, что все допущенные ошибки проявят себя еще на стадии отладки и будут замечены beta-тестерами.

В рамках проекта Synthetix удалось найти несколько простых и надежных решений, не спасающих от ошибок переполнения, но затрудняющих их использование злоумышленниками для несанкционированного вторжения в систему. "StackGuard” – еще одно расширение к компилятору gcc, дополняет пролог и эпилог каждой функции особым кодом, контролирующим целостность адреса возврата.

Алгоритм в общих чертах следующий: в стек вместе с адресом возврата заносится, так называемый, “Canary Word”, расположенный до адреса возврата. Искажение адреса возврата обычно сопровождается и искажением Canary Word, что легко проконтролировать.
Соль в том, что Canary Word содержит символы “\0”, CR, LF, EOF, которые не могут быть обычным путем введены с клавиатуры. А для усиления защиты добавляется случайная привязка, генерируемая при каждом запуске программы.

Компилятор Microsoft Visual C++ так же способен контролировать сбалансированность стека на выходе из функции: сразу после входа в функцию он копирует содержимое регистра-указателя вершины стека в один из регистров общего назначения, а затем сверяет их перед выходом из функции. Недостаток: впустую расходуется один из семи регистров и совсем не проверяется целостность стека, а лишь его сбалансированность.

"Bounds Checker", выпущенный фирмой NuMega для операционной системы Microsoft Windows 9x\NT, довольно неплохо отлавливает ошибки переполнения, но, поскольку, он выполнен не в виде расширения к какому-нибудь компилятору, а представляет собой отдельное приложение, к тому же требующее для своей работы исходных текстов "подопытной" программы, он может быть использован лишь для отладки, и не пригоден для распространения.

Таким образом, никаких готовых "волшебных" решений проблемы переполнения не существует и сомнительно, чтобы они появилось в обозримом будущем. Да и так ли это необходимо при наличие поддержки структурных исключений со стороны операционной системы и современных компиляторов? Такая технология при правильном применении обгоняет в легкости применения, надежности и производительности все остальные, по крайней мере, существующие на сегодняшний день контролирующие алгоритмы.


Содержание раздела