Страницы

Поиск по вопросам

вторник, 17 декабря 2019 г.

Почему LSB ELF shared object можно изменять “на лету”, а executable нет?

#executable #elf #linux


Сразу предупреждаю, вопрос праздный, чисто от любопытства.
Известно, что работающий executable (например a.out) поменять нельзя 

bash: a.out: Text file busy

а с загружаемой shared library (.so) это проходит без проблем. Естественно, изменения
для уже работающих программ будут видны только после dlclose(), dlopen().
Поискал часочек в сети, но ничего не обнаружил. Поскольку (в данный момент) практического
интереса вопрос для меня не имеет (просто интересно) лезть в исходники системы не хочу.
Кто-нибудь может объяснить такое различие в поведении системы (например, fopen("a.out","a+"))
по отношению к этим (в общем, очень похожим (или тут я не прав?)) объектам?
Update
Могу предположить, что .so (аналогично Solaris) отображаются на swap, хотя в Linux
Journal пишут:

...The filesystem cache, program code and shared libraries have a filesystem source,
so the RAM associated with any of them can be reused for another purpose at any time.
Should they be needed again, Linux can just read them back in from disk. ...

Как гуру думают, это объясняет наблюдаемое явление?
UPDATE-2
Про .so
Поскольку для .so делается mmap()  MAP_PRIVATE система по сути включает Copy-on-Write
для .so страниц и при модификации страницы в файле отобразит ее на swap для каждого
процесса, подключившего ее. Так что понятно откуда она подкачиваться будет (если потом
потребуется).
Почему text file busy возникает с a.out, а  с .so нет. 

В переписке долго обсуждается флаг MAP_DENYWRITE и почему его нельзя разрешать устанавливать
из user-mode. (а именно оттуда делается mmap() для .so). При запуске binary ядро этот
флаг устанавливает. 
Лично у меня сложилось впечатление, что достаточно было бы MAP_PRIVATE и для binary,
также как и для .so, но спорить о вопросах безопасности Линусу не хотелось. На самом
деле (практически) MAP_DENYWRITE для исполняемого a.out не мешает, но и не помогает
(IMHO). 
Важно, чтобы изменить код уже исполняющейся программы было трудно.
Пожалуй все, в данном вопросе я свое любопытство (спаcибо @northerner !) удовлетворил,
но пока тему не закрываю. Возможно кто-нибудь захочет обсудить подобные вопросы в своих
ответах.    


Ответы

Ответ 1



Ага, вот вроде бы оно: http://lkml.indiana.edu/hypermail/linux/kernel/0110.0/0476.html. Там довольно обширная дискуссия, сообщений сорок.

Комментариев нет:

Отправить комментарий