[moved from beginners] > Это действительно очень грязный хак, но довольно изящный > :-). И если уж говорить о тараканах в голове, то скорее уж > у разработчиков интела, а не у ленивых программеров. >
Я до сих пор прусь от этой идеи. Ну, молодцы, ребята! Приятно иногда вылезти в интернет и увидеть что не все люди винду без конца ставят как ты, а кто-то и делом занимается. Что касается интеловских инженеров... Тут я лучше ничего не буду говорить. Как можно было до такого состояния довести процессор... всё, молчу. Тут уже у меня одни эмоции остались.
> Нормальным бы был отказ от сегментной > адресации (все равно ее никто толком не использует) и > введение во флаги PDE/PTE бита "Разрешение на выполнение"
Не скажи. Сегментация может быть полезна. А почему до сих пор нету X бита в PTE - этпесдец. Главное, раздельный TLB уже сделали - всего один шажок остался, резервные биты кажись ещё есть... Не будем делать бит "Разрешение на выполнение".
1) Что сидит в CS, DS, SS, когда я в пользовательском режиме во flat-модели?
2) В программе на Delphi в отладчике наблюдаю CS <> DS, DS = SS. Это так и надо? ;-)
3) Для чего нужны регистры ES, FS, GS. Вот в проге на Delphi ES=DS, в FS вообще какая-то дрянь и юзается FS во время инициалицации-финализации модулей. У них есть транскрипция? Ну, к примеру, CS - Code Segment, а GS?
Заранее всем спасибо за ответы.
[IA32] Подведём итоги всему нижесказанному?14.04.04 09:17 Автор: HandleX <Александр М.> Статус: The Elderman
[moved from beginners] 1) Если хотим делать "неисполняемый стек" в OS, никуда не уйти от сегментации, т.е. сегменты кода и стека не должны пересекаться. Или использовать всякие "грязные, но в то же время изящные хаки", могущие снижать быстродействие ;-)
2) Пейджинг в IA32 начинается с загрузки регистра CR3 указателем на Page Directory и установки флага PG в CR0. Если каждый процесс хочет иметь своё уникальное виртуальное адресное пространство (как в Windows, к примеру), без перезагрузки CR3 с каждым переключением контекста не обойтись. При этом нафиг "слетает" TLB, что снижает производительность. Хотелось бы услышать мнения, насколько серьёзно.
3) Рассматривается теоретическая возможность создания OS, в которой вируальная память выделяется процессам сегментами, OS "старается уложить" наиболее активные потоки в 4GB адресное пространство (это для того, чтобы не перегружать CR3), если такое не получается, то OS создаёт дополнительную Page Directory, и перегружает CR3 тогда, когда это необходимо. Каждый процесс имеет свой набор сегментов, в GDT хранятся только наиболее часто используемые (если количество сегментов в системе превысит возможности GDT). Ваше мнение?
4) Слышал, что появившеяся в Pentium II и выше возможность использоватения 4Mb страниц в Page Directory может повысить производительность. Это каким образом? IMHO использование для подкачки страниц такого размера сделает систему более "дёрганной", поскольку прочитать\записать 4Mb на HDD может занимать от полусекунды и более времени. Ваш взгляд на это?
5) У кого-нибудь есть мечта о том, как должно быть реализовано использование совместных библиотек? Подключать нужные сегменты в LDT процесса, который "захотел" использовать библиотеку? Грузить их в некий DLLHelperProcess и использовать какой-нибудь механизм IPC для работы с ними?
7) Я до конца не разобрался, для чего нужен флаг conforming для описателя сегмента. Кто знает, расскажите, зачем он.
Всем заранее большое спасибо за мнения.
Тут вот что пришло в голову по п.211.05.04 20:44 Автор: Den <Денис Т.> Статус: The Elderman
> 2) Пейджинг в IA32 начинается с загрузки регистра CR3 > указателем на Page Directory и установки флага PG в CR0. > Если каждый процесс хочет иметь своё уникальное виртуальное > адресное пространство (как в Windows, к примеру), без > перезагрузки CR3 с каждым переключением контекста не > обойтись. При этом нафиг "слетает" TLB, что снижает > производительность. Хотелось бы услышать мнения, насколько > серьёзно.
Не нужно перегружать CR3.
Если не используем сегментацию, то менеджеру задач достаточно иметь информацию о принадлежности страниц контекстам. Тогда при переключении контекста задачи, менеджер задач должен пометить чужие страницы как выгруженные, а page fault handler при необходимости должен выгрузить чужую страницу в своп и влить на ее место страницу действующего контекста с внесением изменений в информацию о принадлежности к контексту.
Да, есть ещё invlpg, однако непонятно что страшнее — перегружать cr3 или «играться» c каждым переключением контекста с page directory :)12.05.04 07:57 Автор: HandleX <Александр М.> Статус: The Elderman
> Не нужно перегружать CR3. > Если не используем сегментацию, то менеджеру задач > достаточно иметь информацию о принадлежности страниц > контекстам. Тогда при переключении контекста задачи, > менеджер задач должен пометить чужие страницы как > выгруженные,
... и обнулить кэш TLB. А насколько я помню, единственным законным и моделенезависимым вариантом обнуления TLB является презагрузка CR3.
Вот такая вот петрушка :(
Зачем хранить сегменты процессов 3-го кольца в GDT? [updated]15.04.04 14:49 Автор: Den <Денис Т.> Статус: The Elderman Отредактировано 15.04.04 15:42 Количество правок: 1
> 3) Рассматривается теоретическая возможность создания OS, в > которой вируальная память выделяется процессам сегментами, > OS "старается уложить" наиболее активные потоки в 4GB > адресное пространство (это для того, чтобы не перегружать > CR3), если такое не получается, то OS создаёт > дополнительную Page Directory, и перегружает CR3 тогда, > когда это необходимо. Каждый процесс имеет свой набор > сегментов, в GDT хранятся только наиболее часто > используемые (если количество сегментов в системе превысит > возможности GDT). Ваше мнение?
Зачем хранить сегменты процессов 3-го кольца в GDT?
Пускай каждый процесс имеет свою собственную LDT.
> 5) У кого-нибудь есть мечта о том, как должно быть реализовано > использование совместных библиотек? Подключать нужные > сегменты в LDT процесса, который "захотел" использовать > библиотеку? Грузить их в некий DLLHelperProcess и использовать > какой-нибудь механизм IPC для работы с ними?
Грузить DLL'ки в отдельный сегмент и использовать функции библиотеки через ловушки.
Sorry, очепятка - не через ловушки, а через шлюзы вызова.
Насколько я понимаю, запись в LDT суть просто индекс на сегмент в GDT.16.04.04 07:55 Автор: HandleX <Александр М.> Статус: The Elderman
> > > 3) Рассматривается те> Зачем хранить сегменты > процессов 3-го кольца в GDT? > > Пускай каждый процесс имеет свою собственную LDT. > Или я не прав? Таблица (GDT или LDT) выбирается битом в сегментном регистре (нулевым или первым - не помню уже). А сама структура этих таблиц совершенно идентична
[IA32] conforming14.04.04 11:27 Автор: amirul <Serge> Статус: The Elderman
[moved from beginners] > 7) Я до конца не разобрался, для чего нужен флаг conforming > для описателя сегмента. Кто знает, расскажите, зачем он.
Code segments can be either conforming or nonconforming. A transfer of execution into a moreprivileged
conforming segment allows execution to continue at the current privilege level. A
transfer into a nonconforming segment at a different privilege level results in a general-protection
exception (#GP), unless a call gate or task gate is used
Другими словами:
When accessing nonconforming code segments, the CPL of the calling procedure must be equal
to the DPL of the destination code segment; otherwise, the processor generates a general-protection
exception (#GP).
When accessing conforming code segments, the CPL of the calling procedure may be numerically
equal to or greater than (less privileged) the DPL of the destination code segment; the
processor generates a general-protection exception (#GP) only if the CPL is less than the DPL.
CPL - current privilege level, DPL - destination privilege level
Ядро PL==0 может исполнять куски кода в сегментах с PL==3 (например) только если у сегмента третьего кольца есть флаг C (conforming)
[IA32] Ещё вопрос, на этот раз самый нудный (про исполнение кода в стеке)...29.03.04 16:18 Автор: HandleX <Александр М.> Статус: The Elderman
[moved from beginners] Правда ли, что возможность исполнения кода в стеке (в ОС типа NT, LINUX) происходит из-за того, что реализован единый пейджер для flat-модели? И если бы пейджеров было два (один пейджит code segment, другой всё остальное), то тогда сама собой "ушла" бы проблема атаки методом "срыва стека"?
[IA32] Не, дорогой, проблема не в этом30.03.04 03:16 Автор: Zef <Alloo Zef> Статус: Elderman
[moved from beginners] > Правда ли, что возможность исполнения кода в стеке (в ОС > типа NT, LINUX) происходит из-за того, что реализован > единый пейджер для flat-модели? И если бы пейджеров было > два (один пейджит code segment, другой всё остальное), то > тогда сама собой "ушла" бы проблема атаки методом "срыва > стека"?
Срыва бы не было, если бы каждый буфер (массив) аллоцировался в отдельном сегменте с контролем "верха" и "низа", как в 386+ и их в принципе не помещали бы в стеке. Причем, ИМХО, написать компилер, который бы не грешил этим - невозможно, разве что, вообще отказаться от передачи переменных в стеке.
[IA32] Не обязательно каждому фрейму иметь свой сегмент30.03.04 04:05 Автор: amirul <Serge> Статус: The Elderman
[moved from beginners] > Срыва бы не было, если бы каждый буфер (массив) > аллоцировался в отдельном сегменте с контролем "верха" и > "низа", как в 386+ и их в принципе не помещали бы в стеке. > Причем, ИМХО, написать компилер, который бы не грешил этим > - невозможно, разве что, вообще отказаться от передачи > переменных в стеке. Достаточно просто менять в Limit для каждого фрейма (примерно как постоянно перезагружаемый ebp). Только вот это привелегированная инструкция. Но поддержку со стороны компилятора наваять можно. Обращение за границу этого сегмента (даже к адресу возврата) вызывает GP fault, а там уже можно смотреть вызвано ли это командой ret/ret n и прозводится ли чтение.
В принципе реализовать компилятор и сделать stub в ядро довольно несложно. Хотя в этом случае нельзя будет передавать указатели на локальные переменные вниз по функциям - все за пределами текущего фрейма будет недоступно
[IA32] Дык call же не межсегментный30.03.04 09:54 Автор: Zef <Alloo Zef> Статус: Elderman
[moved from beginners] селекторы сегментов данных и указатели внутри них в фрейме задачи валидны для всех подпрограмм
> В принципе реализовать компилятор и сделать stub в ядро > довольно несложно. Хотя в этом случае нельзя будет > передавать указатели на локальные переменные вниз по > функциям - все за пределами текущего фрейма будет > недоступно
в конце концов можно это реализовать и в флэт модели, если все массивы реализовать как объекты по типу жабовских, просто это добавит тормоза на проверку OUT OF RANGE, а сегмент делает то же самое, но аппаратно. Как крайний случай, можно валить все буферы в хип, но это не защитит их от взаимоперекрытия и проги можно будет валить.
[IA32] У меня гораздо лучше идея30.03.04 10:44 Автор: amirul <Serge> Статус: The Elderman
[moved from beginners] > в конце концов можно это реализовать и в флэт модели, если > все массивы реализовать как объекты по типу жабовских, > просто это добавит тормоза на проверку OUT OF RANGE, а > сегмент делает то же самое, но аппаратно. Как крайний > случай, можно валить все буферы в хип, но это не защитит их > от взаимоперекрытия и проги можно будет валить. Так как переполнение буфера всегда происходит последовательно, то защитить можно не все пространство за границей текущего фрейма, а только эту самую границу. Сделать это можно например с помощью debug-регистра. Побочный эффект: softice будет сносить такую защиту на фиг. Кроме того требуется поддержка и от компилятора: каждый фрейм начинать не как
push ebp
mov ebp, esp
а как:
push ebp
mov ebp, esp
call NtProtectNewFrame
Ну а в ядре переставлять защиту фрейма туда-сюда
[IA32] Например в MC680x0 архитектуре29.03.04 19:17 Автор: amirul <Serge> Статус: The Elderman
[moved from beginners] > Правда ли, что возможность исполнения кода в стеке (в ОС > типа NT, LINUX) происходит из-за того, что реализован > единый пейджер для flat-модели? И если бы пейджеров было > два (один пейджит code segment, другой всё остальное), то > тогда сама собой "ушла" бы проблема атаки методом "срыва > стека"? Вообще нет сегментов, зато очень гибкая страничная организация. В том числе можно ставить странице право на исполнение.
[IA32] От DOSа это не спасет, да и шелл можно запустить, где неположено,30.03.04 03:31 Автор: Zef <Alloo Zef> Статус: Elderman
[moved from beginners] если знаешь его адрес и этот адрес положишь на стек. Тут только полный отказ от указателей и реализация массивов, как объектов (с встроенным контролем переполнения), типа, как в Жабе, поможет.
[IA32] От доса ничего не спасет30.03.04 03:59 Автор: amirul <Serge> Статус: The Elderman
[moved from beginners] > если знаешь его адрес и этот адрес положишь на стек. Тут А если нет никакого адреса шелла. В смысле можно конечно положить например адрес ShellExecute, но надо еще выложить агрументы а с указателями подгадать не так уж легко. Особенно если потрудиться немного и рандомизировать начальный адрес стека
> только полный отказ от указателей и реализация массивов, > как объектов (с встроенным контролем переполнения), типа, > как в Жабе, поможет. Гы, а потом еще сборку мусора и прощай эффективность.
Как говорится, я поверю в эффективность языка только если его следующие версии будут писаны на предыдущих. Представляю себе раскрутку жабы версии 10.0, последовательно запускающую все виртуальные машины вплоть до 1.4 или еще раньше :-)
[IA32] стек29.03.04 17:25 Автор: NKritsky <Nickolay A. Kritsky> Статус: Elderman
[moved from beginners] > Правда ли, что возможность исполнения кода в стеке (в ОС > типа NT, LINUX) происходит из-за того, что реализован > единый пейджер для flat-модели?
Возможность исполнения кода в стеке происходит из-за того что стек может быть адресован по CS:XXXXXXXX . Вот и все. Что такое единый пэйджер я не очень понял.
> И если бы пейджеров было > два (один пейджит code segment, другой всё остальное), то > тогда сама собой "ушла" бы проблема атаки методом "срыва > стека"?
Короткий ответ: Нет.
Длинный ответ: Разруха не в сортирах, она в головах. Даже если ты реализуешь защиту от исполнения в стеке. Которая кстати возможна даже на flat варианте аля NT/IA-*NIX . Ищи доку по ключевым словам SolarDesigner, TLB cache, stack. Так вот, даже если ты сможешь защититься от исполнения кода в стеке, проблема buffer overflow все равно останется. Есть всякие варианты обхода неисполняемого стека.
Нет все таки разруха в сортирах. Очень плохо представляю как можно было...29.03.04 19:26 Автор: amirul <Serge> Статус: The Elderman Отредактировано 29.03.04 19:27 Количество правок: 1
[moved from beginners] > Короткий ответ: Нет. > Длинный ответ: Разруха не в сортирах, она в головах. Даже > если ты реализуешь защиту от исполнения в стеке. Которая > кстати возможна даже на flat варианте аля NT/IA-*NIX . Ищи > доку по ключевым словам SolarDesigner, TLB cache, stack. Нет все таки разруха в сортирах. Очень плохо представляю как можно было это сделатьна ia32, а доки искать щас лень (может быть позже). Но если что-то сделать можно, но через %опу. То в том, что это не сделано виноват не столько я, сколько тот, кто поставил такой выбор