22.1. Когда безопасность имеет значение?
22.1. Когда безопасность имеет значение?
Компьютерные программы — это очень сложные вещи. Даже самая простая программа "Hello World" является на удивление запутанной. Игнорируя все, что происходит в ядре, библиотека С должна отыскать соответствующие совместно используемые библиотеки, загрузить их в систему, инициализировать стандартные методы ввода-вывода. На компьютере, с помощью которого готовилась данная глава, полная программа состояла из 25 системных вызовов. Только один из них оказался вызовом функции write(), который использовался непосредственно для вывода слов "Hello World".
С увеличением функциональности программ очень быстро возрастает их сложность. Большинство реально работающих программ принимают входные данные из нескольких источников (например, из командной строки, файлов конфигурации, терминала) и обрабатывают полученные данные сложными способами. Любая ошибка в процессе может вызвать непредсказуемое поведение, однако опытный программист чаще всего обрабатывает такие сюрпризы без появления нежелательных последствий. Если в эту "адскую смесь" добавить еще несколько сложных библиотек, то любому программисту (не говоря о команде программистов) будет очень трудно полностью представить себе реакцию программы на определенный набор входных данных.
Большинство программ очень внимательно тестируются, для гарантии того, что они дают соответствующие результаты для корректных наборов входных данных. При этом работа большинства программ с неожиданными входными данными проверяется недостаточно[156]. Несмотря на то что при проектировании ядра тщательно учитывается необходимость предотвращения риска для системы из-за неисправностей в пользовательских программах, все же ошибки в некоторых типах программ могут отразиться на целостности системы.
Существуют три типа программ, при создании которых программисты должны постоянно помнить о безопасности.
• Программы, обрабатывающие данные, которые могут поступать из ненадежных источников, очень уязвимы. Такие данные могут содержать скрытые атаки, использующие программные ошибки и вызывающие непредсказуемое поведение программ. Нередко целью таких атак является получение полного доступа к компьютеру для анонимных пользователей. Любая программа, имеющая доступ к данным через сеть (как клиентская, так и серверная) становится потенциальным мишенью для атак. Но даже безобидные программы вроде текстовых процессоров, могут быть поражены через поврежденные файлы данных[157].
• Программы, которые во время запуска могут переключаться между пользовательскими или групповыми контекстами (через биты setuid и setgid в исполняемом файле), несут потенциальную опасность передачи прав и информации привилегированного пользователя другому (непривилегированному) пользователю.
• Любая программа, работающая как системный демон, может вызвать проблему безопасности. Подобные программы работают в системе как привилегированные пользователи (довольно часто они выступают в качестве root), поэтому любое взаимодействие с обычными пользователями подвергает систему опасности.