OberonCore
https://forum.oberoncore.ru/

W^X при динамической загрузке модулей
https://forum.oberoncore.ru/viewtopic.php?f=134&t=7026
Страница 1 из 1

Автор:  Alexander Shiryaev [ Четверг, 25 Сентябрь, 2025 23:23 ]
Заголовок сообщения:  W^X при динамической загрузке модулей

В одном непрерывном куске памяти подряд расположены metadata, code и область для глобальных переменных.

Сейчас память выделяется одним mmap, и получается, что на одной странице могут оказаться и данные, и код. Из-за этого не получается разделить права: хотелось бы, чтобы код был PROT_READ|PROT_EXEC, а данные — PROT_READ|PROT_WRITE. Но mprotect работает постранично, и получается, что память приходится помечать RWX.

В Linux и FreeBSD это ещё разрешено, но в OpenBSD с политикой W^X это не работает.

Есть ли способ реализовать настоящую модель W^X (чтобы код был только RX, а данные только RW), не меняя генерацию объектных файлов? Или всё-таки нужно править компилятор/эмиттер и добавлять paddings, чтобы code и metadata всегда выравнивались на границу страницы?

Автор:  JackKatch [ Пятница, 26 Сентябрь, 2025 08:54 ]
Заголовок сообщения:  Re: W^X при динамической загрузке модулей

Не знаю каков формат объектного файла у BlackBox, а в "Виртовской модели" (см. Проект Оберон) переменные находятся по отрицательным смещениям. Если константы и код выровнять по началу страницы, то всё остальное будет выше, т.е. в другой странице. Вроде бы ни каких проблем нет.

Автор:  Trurl [ Пятница, 26 Сентябрь, 2025 14:55 ]
Заголовок сообщения:  Re: W^X при динамической загрузке модулей

Загрузчик можно переписать, чтобы код и данные раздельно грузил. Но интерфейс к ядру придется изменить.

Автор:  Alexander Shiryaev [ Пятница, 26 Сентябрь, 2025 16:39 ]
Заголовок сообщения:  Re: W^X при динамической загрузке модулей

Trurl писал(а):
Загрузчик можно переписать, чтобы код и данные раздельно грузил. Но интерфейс к ядру придется изменить.

Я так понял, нужно поменять реализацию StdLoader.Fixup?

Автор:  Trurl [ Суббота, 27 Сентябрь, 2025 16:35 ]
Заголовок сообщения:  Re: W^X при динамической загрузке модулей

И еще вызовы Fixup. Там память выделяется двумя блоками, потом в один из них загружается код вместе с данными, а в Fixup передаются адреса внетри блока.
Код:
Kernel.AllocModMem(mod.ds, mod.ms + mod.cs + mod.vs, mod.dad, mod.mad);
(* выделяем блок для дескрипторов (1) и для всего остального (2) *)
..
 inp.ReadBytes(mp^, 0, mod.ms);
(* загружаем константы в блок (2) *)
 inp.ReadBytes(dp^, 0, mod.ds);
(* загружаем дескрипторы в блок (1)  *)
 inp.ReadBytes(mp^, mod.ms, mod.cs);
(* загружаем код  в блок (2), после констант, а после кода - место для переменных *)
 ...
  Fixup(mod.mad, mod); (* фиксим  ссылки на константы *)
  Fixup(mod.dad, mod); (* фиксим  ссылки на дескрипторы *)
  Fixup(mod.mad + mod.ms, mod); (* фиксим  ссылки на код *)
  Fixup(mod.mad + mod.ms + mod.cs, mod); (* фиксим  ссылки на переменные *)

И в самом Fixup такое же размещение подразумевается
Код:
 linkadr := mod.mad + mod.ms + link
 linkadr := mod.mad + link
 linkadr := mod.dad + link - mod.ms

Автор:  Alexander Shiryaev [ Среда, 01 Октябрь, 2025 22:34 ]
Заголовок сообщения:  Re: W^X при динамической загрузке модулей

Спасибо. Похоже всё работает.

Сделал 4 (page-aligned) области памяти вместо 2-х:
d (desc), m (meta + code + var) →d (desc), m (meta), c (code), v (var)

mod.mad + mod.ms → mod.cad
mod.mad + mod.ms + mod.cs → mod.vad

права доступа:
  • desc: write, read
  • meta: read
  • code: exec, read
  • var: write, read

BlackBox заработал в OpenBSD 7.7 (пока только CLI, GUI не пробовал)

В моём "ретро"-репозитории


Но ещё в Kernel есть такое место:

Код:
PROCEDURE InvalModMem (modSize, modAdr: INTEGER);
BEGIN
   DEC(used, modSize);
   HeapFree(modAdr, modSize)
END InvalModMem;

которое используется в Kernel.UnloadMod:
Код:
IF dyn IN mod.opts THEN   (* release memory *)
   InvalModMem(mod.data + mod.dsize - mod.refs, mod.refs)
END

Что с этим делать?

Автор:  Trurl [ Четверг, 02 Октябрь, 2025 21:51 ]
Заголовок сообщения:  Re: W^X при динамической загрузке модулей

Область дескрипторов оставить, остальные три освободить.Так же сейчас работает.

Автор:  arisu [ Четверг, 09 Октябрь, 2025 12:20 ]
Заголовок сообщения:  Re: W^X при динамической загрузке модулей

а ещё можно кому-то сходить в LC и забрать из евойной Kernel полноценный сканер объектов модуля, который позволяет безопасно освобождать всю память модуля, а не как сейчас — оставляя каждый раз мусор и протекая. для этого чуть-чуть изменён формат объектных файлов (обратно совместим, старые объектные файлы будут выгружаться по старому алгоритму, потому что там недостаточно информации) и добавлен новый сканер на выгрузку. формат хипа я не менял.

Автор:  Alexander Shiryaev [ Четверг, 09 Октябрь, 2025 19:51 ]
Заголовок сообщения:  Re: W^X при динамической загрузке модулей

arisu писал(а):
а ещё можно кому-то сходить в LC и забрать из евойной Kernel полноценный сканер объектов модуля, который позволяет безопасно освобождать всю память модуля, а не как сейчас — оставляя каждый раз мусор и протекая. для этого чуть-чуть изменён формат объектных файлов (обратно совместим, старые объектные файлы будут выгружаться по старому алгоритму, потому что там недостаточно информации) и добавлен новый сканер на выгрузку. формат хипа я не менял.

но fossil-репозиторий с LC недоступен...

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/