| OberonCore https://forum.oberoncore.ru/ |
|
| W^X при динамической загрузке модулей https://forum.oberoncore.ru/viewtopic.php?f=134&t=7026 |
Страница 1 из 2 |
| Автор: | 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 права доступа:
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 недоступен... |
|
| Автор: | arisu [ Пятница, 10 Октябрь, 2025 14:31 ] |
| Заголовок сообщения: | Re: W^X при динамической загрузке модулей |
вообще-то должен быть доступен. для клонирования вообще проверки отключены, а для веб-интерфейса надо пройти простенький челлендж, даже печеньки включать не надо. если вас не пускает даже в челлендж — попробуйте тор. потому что украинские ip — как ни смешно — блокируются с российской стороны в оба направления. сюда вот я через тор хожу, и до меня многие из рф достучаться не могут напрямую. от провайдера/хостера зависит, насколько я понял. впрочем, я наивно предполагал, что у всех заинтересованых репозиторий давно склонирован. там в эти несколько лет ничего нового не появилось, к сожалению. |
|
| Автор: | arisu [ Пятница, 10 Октябрь, 2025 14:48 ] |
| Заголовок сообщения: | Re: W^X при динамической загрузке модулей |
только дошло. про «кому-то сходить» — это я не ехидничал, а имел в виду, что там всё равно придётся разбираться (хотя большинство кода в одной кучке, но и смотреть изменения в писалке объектных файлов придётся, например, и небольшие, хоть и совместимые, изменения записи модуля в Kernel), так что я имел в виду: «кому-то, у кого есть время и вдохновение». |
|
| Автор: | Alexander Shiryaev [ Пятница, 10 Октябрь, 2025 17:21 ] |
| Заголовок сообщения: | Re: W^X при динамической загрузке модулей |
arisu писал(а): вообще-то должен быть доступен. для клонирования вообще проверки отключены, а для веб-интерфейса надо пройти простенький челлендж, даже печеньки включать не надо. если вас не пускает даже в челлендж — попробуйте тор. потому что украинские ip — как ни смешно — блокируются с российской стороны в оба направления. сюда вот я через тор хожу, и до меня многие из рф достучаться не могут напрямую. от провайдера/хостера зависит, насколько я понял. впрочем, я наивно предполагал, что у всех заинтересованых репозиторий давно склонирован. там в эти несколько лет ничего нового не появилось, к сожалению. Из Казахстана: вчера был редирект на fuck.off, сегодня был доступен, сейчас снова редирект. С российского VPN: вчера вроде бы был редирект на fuck.off, сегодня работает. С VPN USA: недоступен (соединение с сервером устанавливается, но после отправки запроса не получается ответ). |
|
| Автор: | arisu [ Суббота, 11 Октябрь, 2025 03:56 ] |
| Заголовок сообщения: | Re: W^X при динамической загрузке модулей |
да не надо туда браузером ходить: просто фоссилом напрямую клонировать. там довольно дубовая защита от «аи»-ботов, которые мне сервер чуть не завалили, а fossil clone/pull пускают напрямую. только не после посылания — тогда надо денёк выждать, кулдаун будет. впны же в большинстве своём поблочены, потому что приходят с помоек типа digital ocean, которые мне сервер постоянно долбят попытками поиска «сплоетов», за то и забанено всё скопом. там в веб-интерфейсе реально делать нечего: вы после клона сделаете fossil ui reponame — и получите точно такой же, но локальный. фоссил склонирует всё, что есть — и код, и вики, и билетики. |
|
| Автор: | arisu [ Суббота, 11 Октябрь, 2025 04:04 ] |
| Заголовок сообщения: | Re: W^X при динамической загрузке модулей |
и, кстати, там в Docu/Kernel.odc есть небольшое описание того, как работает менеджер памяти: «Memory Manager Details (WIP)» в конце. совсем мало, но лучше, чем ничего. можете себе забрать, они у нас одинаковые. впрочем, мой менеджер памяти чуть-чуть лучше оригинального в плане управления кластерами: он в состоянии их отдавать системе, если они долго не использовались. и ещё там есть важный фикс: когда выделяется большой кластер (очень большой массив, например), и потом GC его собирает, то оригинальный BBCB использует этот «огромный кластер» для выделения маленьких объектов. и может заякорить его низачем вместо чтобы вернуть системе. оно не то чтобы фатально (оригинал довольно плохо умеет кластеры возвращать), но неприятно. это у меня тоже починено. ещё я оттуда COM к чёртовой бабушке выпилил (как и из компилятора), но если надо — восстановить не особо проблема, я думаю. |
|
| Автор: | Alexander Shiryaev [ Воскресенье, 12 Октябрь, 2025 13:38 ] |
| Заголовок сообщения: | Re: W^X при динамической загрузке модулей |
Trurl писал(а): Область дескрипторов оставить, остальные три освободить.Так же сейчас работает. Нужно освободить 3 области:
Как было: Код: InvalModMem(mod.data + mod.dsize - mod.refs, mod.refs) mod.refs = meta address mod.data = var address mod.dsize = var size mod.data + mod.dsize - mod.refs = var address + var size - meta address = meta size + code size + var size (так как это всё было в одном куске памяти) Сейчас вместо этого нужно вызвать:
meta address = mod.refs code address = mod.code var address = mod.dsize похоже code size — это mod.csize с выравниванием по 4 Б: code size = ((mod.csize - 1) DIV 4 + 1) * 4 var size = mod.dsize но где взять meta size? mod.rsize — это только часть meta size |
|
| Автор: | arisu [ Воскресенье, 12 Октябрь, 2025 13:44 ] |
| Заголовок сообщения: | Re: W^X при динамической загрузке модулей |
ну так получается, что рефсайз — это конечный адрес модуля минус мод.рефс, нет? |
|
| Автор: | Alexander Shiryaev [ Воскресенье, 12 Октябрь, 2025 13:58 ] |
| Заголовок сообщения: | Re: W^X при динамической загрузке модулей |
arisu писал(а): ну так получается, что рефсайз — это конечный адрес модуля минус мод.рефс, нет? Что такое конечный адрес модуля? meta = refs + Export + Pointers + Perpare Type Descriptors + Import List + Names + Const (см. DevCPE.OutCode) mod.refs = meta address mod.rsize — похоже это только refs size |
|
| Автор: | Alexander Shiryaev [ Вторник, 14 Октябрь, 2025 07:11 ] |
| Заголовок сообщения: | Re: W^X при динамической загрузке модулей |
Похоже придётся при выделении памяти для meta добавить 4 Б в самом начале этого куска памяти для хранения meta size. |
|
| Автор: | Trurl [ Вторник, 14 Октябрь, 2025 17:54 ] |
| Заголовок сообщения: | Re: W^X при динамической загрузке модулей |
Похоже на то. Размеры областей нигде не сохраняются. Ну, можно еще в поле Module.ext запихнуть, но это как-то того. |
|
| Автор: | Alexander Shiryaev [ Пятница, 17 Октябрь, 2025 09:06 ] |
| Заголовок сообщения: | Re: W^X при динамической загрузке модулей |
Так и сделал Код: IF dyn IN mod.opts THEN (* release memory *)
- InvalModMem(mod.data + mod.dsize - mod.refs, mod.refs) + IF mod.dsize # 0 THEN InvalModMem(mod.dsize, mod.data) END; + S.GET(mod.refs - SIZE(INTEGER), i); InvalModMem(i, mod.refs - SIZE(INTEGER)); + InvalModMem(((mod.csize - 1) DIV 4 + 1) * 4, mod.code) END |
|
| Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |
|