> Извините, что не в форуме "operating systems". Этот вопрос > скорее туда. > > Что заставляет разработчиков ОС делать сегмент стека > исполняемым? > Это беда самых популярных ОС. Хочется понять причины, > которые к приводят к такому положению.
Причина очень простая - скорость доступа к стеку ...
> > Наверняка создателям приходили в голову такие вопросы...
Есть различные способы сделать стек неисполняемым (либо отследить сискол из сегмента стека) в том числе и для x86
наиболее популярные решения для x86
это
1) PAX (есть реализации для linux и NT)
2) openwall (для linux)
Извините, что не в форуме "operating systems". Этот вопрос скорее туда.
Что заставляет разработчиков ОС делать сегмент стека исполняемым?
Это беда самых популярных ОС. Хочется понять причины, которые к приводят к такому положению.
Наверняка создателям приходили в голову такие вопросы...
исполняемый стек19.06.03 13:22 Автор: XR <eXtremal Research> Статус: The Elderman
> Извините, что не в форуме "operating systems". Этот вопрос > скорее туда. > > Что заставляет разработчиков ОС делать сегмент стека > исполняемым? > Это беда самых популярных ОС. Хочется понять причины, > которые к приводят к такому положению.
Причина очень простая - скорость доступа к стеку ...
> > Наверняка создателям приходили в голову такие вопросы...
Есть различные способы сделать стек неисполняемым (либо отследить сискол из сегмента стека) в том числе и для x86
наиболее популярные решения для x86
это
1) PAX (есть реализации для linux и NT)
2) openwall (для linux)
Sorry, вопрос может и глуп, но все же: а почему бы приложению, которое хочет защититься таким образом, не вызвать VirtualProtect ?21.06.03 09:59 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 21.06.03 10:02 Количество правок: 1
Насколько я зная компиляторы могут что то подобное юзать опционально ... но там это дело вроде бы используется не для защиты как таковой а для контроля размера стека - типа нарушил защиту - раздвинул стек ... НО проблемы это не снимает да и используется эта фича в отладочном режиме (то что это тормоза совершенно очевидно )- я к сожалению особо подробно в это дело не вникал может кто сможет рассказать про это дело более развернуто
Re[2]: VirtualProtect24.06.03 16:17 Автор: amirul <Serge> Статус: The Elderman
> Насколько я зная компиляторы могут что то подобное юзать > опционально ... но там это дело вроде бы используется не ВиртуалПротект может менять права на СТРАНИЦЫ, а в x86 архитектуре нельзя выставлять страницам запрет на исполнение (исполнение можно разрешать/запрещать только СЕГМЕНТАМ). Стек в любом случае должен оставаться RW, а даже если и запретить для селектора SS исполнение, то, как уже было замечено, flat модель позволяет обратиться к той же странице через другой селектор (в частности cs, для которого исполнение должно быть всегда).
> для защиты как таковой а для контроля размера стека - типа > нарушил защиту - раздвинул стек ... НО проблемы это не Guard Page в стеке есть всегда (и в Release тоже - это фича ОСи, а не компилятора) и у нее сброшен бит P (present). В Optional Header-е у PE exe-шника указывается Stack Commit Size (по умолчанию 0x4000) - сколько стека физически выделяется при создании процесса, и Stack Reserved Size (по умолчанию 0x100000) - до каких пор может расти стек за счет этой самой Guard Page. Стек расширяется в обработчике Page Fault-а, когда происходит обращение к Guard Page-у, а сама эта пага сдвигается дальше.
> снимает да и используется эта фича в отладочном режиме (то > что это тормоза совершенно очевидно )- я к сожалению особо > подробно в это дело не вникал может кто сможет рассказать > про это дело более развернуто В общем случае проблему срыва стека на x86 flat модели решить нельзя. Расширение стек-фрейма для функции и введение туда разных проверочных данных помогает только для отладки своих программ, т.к. эксплоит, который сорвал стек процесса чаще всего никогда не возвращает управление и следовательно никогда не выполняет код, который мог бы проверить состояние стека на выходе из функции.
Да, печально. Остался последний вопрос...25.06.03 20:36 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 25.06.03 20:37 Количество правок: 1
Столько приятных на первый взгляд режимов доступа к страницам открывает VirtualProtect... Однако PAGE_READWRITE функционально равно PAGE_EXECUTE_READWRITE на Intel... Столько режимов из-за мультиплатформенности, т.е. на других платформах (NT4 + DEC Alpha, к примеру), это не так?
Да, печально. Остался последний вопрос...26.06.03 12:58 Автор: amirul <Serge> Статус: The Elderman
> Столько приятных на первый взгляд режимов доступа к > страницам открывает VirtualProtect... Однако PAGE_READWRITE > функционально равно PAGE_EXECUTE_READWRITE на Intel... > Столько режимов из-за мультиплатформенности, т.е. на других > платформах (NT4 + DEC Alpha, к примеру), это не так?
Ага. Причем ноги у сегментации растут от backward compatibilyty с 8086 и т.д.. На том же 680x0 все необходимое разделение можно сделать при помощи страниц. И запретить исполнение в странице тамошний MMU может. Причем возможно до 5 уровней разбиения на страницы с произвольной (устанавливаются в спец регистрах) битовостью каждого уровня. В x86 существует только 3 жестко заданных уровня: 10 бит - индекс в PD, 10 - в PT, и 12 - смещение на странице.
Кста, flat-модель - не столько признак криворукости или лени программистов, сколько забота о портабельности. Уж очень на многих платформах вообще не существует понятия подобного сегментам (всегда удобнее работать с линейной памятью). И вся необходимая функциональность ложится на страничный обмен. И это правильно. Как сказал еще Оккам: "Не вводи сущности сверх необходимости". Два механизма, выполняющие в сущности одно и то же - явный перебор.
Ничего не имею против Intel, но x86 - не самый лучший пример продуманной архитектуры.
> Причина очень простая - скорость доступа к стеку ... Хым... непонятно, почему
push, pop, call, ret, ...
- замедлятся, если убрать флаги исполняемости?
> Есть различные способы сделать стек неисполняемым (либо > отследить сискол из сегмента стека) в том числе и для x86 Проверка сис-call-ов - хорошая идея...
> наиболее популярные решения для x86 > > это > > 1) PAX (есть реализации для linux и NT) > 2) openwall (для linux)
исполняемый стек19.06.03 14:40 Автор: cb <cb> Статус: Member
> > Причина очень простая - скорость доступа к стеку ... > Хым... непонятно, почему > push, pop, call, ret, ... > - замедлятся, если убрать флаги исполняемости? AFAIK x86 это (nonexec page) не умеет (PAX правда умеет это обходить через одно место :))
а размещать стек в своем сегменте это обрекать себя на межсегментные переключения ...
> > > Есть различные способы сделать стек неисполняемым > (либо > > отследить сискол из сегмента стека) в том числе и для > x86 > Проверка сис-call-ов - хорошая идея...
Ну да - когда точно известна структура памяти user space задачи
это работает (см openwall)
http://www.openwall.com
> > наиболее популярные решения для x86 > > > > это > > > > 1) PAX (есть реализации для linux и NT) > > 2) openwall (для linux)
Я вообще до сих пор не втыкаюсь, почему все операционки юзают флэт модель? Размещение буферов каждого в своем сегменте позволяет на системном уровне "железно" защитить их от переполнения. Селекторы кэшируются и для современных камней потери на переключение незначительны, а безопасность и стабильность системы возрастает многократно.
> Я вообще до сих пор не втыкаюсь, почему все операционки > юзают флэт модель? > Селекторы кэшируются и для современных > камней потери на переключение незначительны, Опять непонятно: о каком переключении сегментов идет речь?
Например: SS указывает в один сегмент, DS - в другой, и переключения задач не происходит.
Подведем итоги.
Выслушав все замечания, раскопав пыльную книжку про защищенный режим процессоров x86, можно сделать выводы:
1. вся фигня из-за флэт модели
2. page-таблица в PM режиме не позволяет различать флаги чтения от исполнения для страницы
Несмотря на то, что дескрипторы для SS, DS, ES, FS могут иметь "правильные" флаги, из-за флэт модели возможно записать в одно место памяти через эти сегментные регистры, а затем исполнить его через CS.