|
|
ru.linux- RU.LINUX --------------------------------------------------------------------- From : Zahar Kiselev 2:5030/382.1 14 Oct 2004 00:29:08 To : Nick Gazaloff Subject : Re: неисполняемый стэк в 2.4 ? -------------------------------------------------------------------------------- Oct 13 23:07 04, Nick Gazaloff wrote to Zahar Kiselev: NG> Сегмент стека (мы ведь о нем говорим) _обязан_ быть сегментом данных NG> (не кода), и обязательно read-write. Согласен. NG> При этом код, помещенный в него, может NG> исполняться. Hикакой аппаратнной защиты нет. Опять смотрим в книгу Орловского, на которую я уже ссылался. Страница 66. Таблица "Байт прав доступа дескрипторов сегментов кодов/данных". Третий бит - _отдельный_ признак исполняемости. Первый бит - разрешение записи. То есть разрешение записи не зависит от разрешения исполнения - это _разные_ биты. Вот сделать нечитаемый, но при этом исполняемый сегмент - не получится, так как отдельного бита на разрешение чтения - нет. А такой чтобы R/W, но при этом не исполняемый - можно. Соответственно можно и незаписываемый, но исполняемый сегмент кода, что тоже полезно. NG> Да и странно было бы, если бы она была, но _ни_одна_ (!) ОС на x86 ее NG> не использовала. Ты хочешь сказать, что знаешь внутренности _всех_ систем на x86, включая редкие и экзотические? Я про себя такое утверждать не рискну. Зато когда-то я очень любил возиться с такой забытой сейчас штукой как дос-экстендеры. Вот они, в отличие от Линукса, были сделаны на основе именно сегментного, а не страничного механизма - так как свопа, для которого одинаковые страницы удобны, там небыло, а вот удобные для программиста сегменты - были. Можно было например даже поместить массив в отдельный сегмент - и при вылезании за его границу процессор сам обнаруживал ошибку в программе. Или те данные, которые не должны модифицироваться - засунуть в r/o сегмент - и тоже получить ошибку если случайно в них полезешь что-то писать. Еще там проверялись межсегментные передачи управления - просто так в любое место "дальний jmp" не сделаешь - надо чтобы в сегментной части адреса были именно адрес заранее созданного правильного сегмента, а в смещении - число, не превышающее его заданный размер. Атрибуты и размеры сегментов задавались при сборке программы в специальном управляющем файле для линкера. Возиться с этим было весьма интересно. Я сожалею, что в Линуксе нам не предлагается "внутрипрограммное" использование встроенных в процессор механизмов защиты. Выдали кусок памяти, поделили на код и данные, засунули туда программу и она там что угодно может делать, ну разве что система наверно не даст писать в сегмент кода. А данные все одним куском лежат и неправомерные обращения не отслеживаются. То же самое и с переходами и вызовами подпрограмм в сегменте кода - при косвенном вызове по неправильно сформированному адресу - легко попасть "пальцем в небо", а вылезет это только когда среди тех случайных байтов куда попали - встретится какая-нибудь неразрешенная в пользовательском режиме команда, а это может произойти довольно далеко от точки перехода, особенно если попали в массив нулевых байтов. Вот тут кстати разработчики процессора немного промахнулить - надо бало попытку исполнения команды, состоящей из нулевых байтов - интерпретировать если не как ошибку,то хотябы как вызов отладчика. Hадеюсь, что за давностью лет не сильно напутал в своих воспоминаниях о дос-экстендерах... Zahar(@spbdept.rbc.ru) Остров Большой Березовый: http://birch-island.spb.ru --- Msged/LNX 6.1.1 * Origin: N:60.17'54" E:28.39'40" (2:5030/382.1) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.linux/3288416d551e.html, оценка из 5, голосов 10
|