> Во-первых не ALSR, а ASLR (Address Space Layout Randomization), а во-вторых я
> таки понял зачем вам адресация относительно eip.Затем чтобы грузить программу в произвольный адрес и не патчить потом полпрограммы, очевидно.
> Так вот, сам по себе ASLR это такой необходимый костыль из-за использования
> flat memory model.
У этой самой flat memory model при наличии MMU как бы есть страницы и есть разные права на оные, из которых делается все что угодно. Из страниц и их атрибутов можно сэмулировать сегменты. Из сегментов страничная память не эмулируется. Вывод: MMU с страничной адресацией - это суперсет, а не subset технологий. Это шаг вперед. И линейная адресация, и возможность защиты памяти программ друг от друга и ОС от программ, и виртуальная память. Все и сразу.
> Вы можете записать что угодно в память, а потом передать туда управление.
На самом деле это ниоткуда не следует: все от атрибутов страниц зависит. NX бит - всего лишь логичное доразвитие идеи MMU и страничной адресации. А оно даже без NX бита как минимум вполне справлялось с изоляцией ОС от процессов и процессов друг от друга.
> Та security model которую проектировали для PM
> в 286+ делала использования ASLR банально не нужным
ASLR не замена NX бита. А дополнение к оному. И да, я не вижу чем защита памяти через сегменты лучше защиты памяти через MMU и атрибуты страниц. MMU + атрибуты страниц может изобразить любой мыслимый сегмент с гранулярностью равной размеру страницы. А вот обратный вариант не катит.
> т.к. модификацию сегментов кода можно ограничить где-то на ring0 вместе
> с vmm, планировщиком и обработчиками исключения.
А что не дает сделать то же самое с MMU и атрибутами страниц? Попробуйте из ring3 сунуться в память операционки или другого процесса влобовую, а не через услуги ОС, расскажите как получилось. Своп кстати является "штатным" исключением - если нужной страницы нет, случается эксепшн и его обработчик должен обеспечить догрузку с диска нужной страницы до возобновления работы задачи. А потом обработчик вернет состояние проца в вид "как было" и задача не узнает что оказывается был какой-то там page fault вообще :)))
> Всё остальное (дрова, системные сервисы, юзерленд) крутить
> на более низких уровнях.
Внезапно, деление на кернел и юзер ничего такого не запрещает. Можно даже писать user-mode драйвер, который для того чтобы выполнить некое действие будет просить привилегированный кусок ядра отработать ему опасную операцию. Для этого достаточно 2 уровней, юзер и система. Больше - в принципе конечно лучше, но вот исторически все как-то забили на эту фичу х86 и дружно юзали ring0 и ring3, тем более что у других процов есть эквиваленты оных, что позволяет проще портировать операционку на другие процессоры ("kernel mode" и "user mode" в общем случае).