Существует ли механизм защиты приложений во время обновления библиотеки?

10

Если пользователь работает с приложением, которое динамически связано, и система обновляется, существует ли какой-либо механизм защиты, который предотвращает повреждение приложения?

Или это до применения?

Sevo
источник
Помните , чтение книги Linux о том , как следует использовать ln -sfпри замене через библиотеку, потому что -fпозволил вам «перезаписи» существующему назначение символической ссылки с новым, без него когда - либо «сломан» ( в отличие , если ты с rmпоследующим а ln -s) Поэтому перед командой library.so указал на старую версию, например. library.so.4 ... после команды, он просто указал на library.so.5 (или любой другой ) , вместо этого - никогда не не указывая на действительной библиотеке.
Баард Копперуд

Ответы:

16

Как упоминает @Kusalananda, обычно обновления выполняются путем удаления старого файла и создания нового с тем же именем. Это фактически создаст новый файл с новым индексом, оставляя систему свободной, чтобы использовать старый, пока он открыт.

В качестве упрощенного примера, такие вещи, как

rm /bin/cat
cp /new/version/of/cat /bin/cat

создаст логически новый файл и работает, даже если catможет быть запущен. То же самое касается библиотек. (Выше приведен пример, а не надежный способ обновления файла в реальном мире.)


Кто-то может попытаться изменить двоичный файл вместо создания нового с тем же именем. В этом случае, по крайней мере, Linux фактически предотвращает внесение изменений в исполняемый файл, который используется:

window 1 # ./cat
window 2 # echo foobar > cat
-bash: cat: Text file busy

Тем не менее, это не похоже на работу с динамически загружаемыми библиотеками ...

Я сделал копию libc.so.6для тестирования и заполнил ее нулями, пока она использовалась:

window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ldd ./cat
    linux-vdso.so.1 (0x00007ffcfaf30000)
    libc.so.6 => /tmp/lib/libc.so.6 (0x00007f1145e67000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f1146212000)

window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ./cat
foo
foo

Segmentation fault

(Между тем в другом окне, после foo, до сегфоута)

window 2 /tmp/lib# dd if=/dev/zero of=libc.so.6 bs=1024 count=2000

На самом деле сама программа ничего не могла с этим поделать, поскольку я эффективно редактировал ее код в Интернете.

(Вероятно, это будет зависеть от системы, я тестировал на Debian Jessie 8.5, Linux 3.16.7-ckt25-2 + deb8u3. В частности, системы Windows IIRC еще более агрессивны в отношении предотвращения изменения используемых файлов.)


Поэтому я полагаю, что ответ заключается в том, что обновления обычно выполняются таким образом, чтобы избежать каких-либо проблем, и этому помогают внутренние компоненты файловой системы. Но (в Linux), похоже, нет никаких гарантий против фактического повреждения динамических библиотек.

ilkkachu
источник
installУтилита обычно используется для вещей , как это. Вам не нужно явно rmуказывать файл назначения. Кроме того, он сохраняет права доступа к существующему файлу, может сделать резервную копию, установить новый режим и т. Д. Пример использования:install /new/version/of/cat /bin/cat
Патрик
Конечно. rm+ cpПредназначались в качестве примера. Также может быть разумно поместить новый файл атомарно с переименованием, избегая короткого окна, в котором ни одна версия не доступна. (Хотя GNU install, похоже, даже этого не делает, hmpf.)
ilkkachu
2
Я хотел бы прояснить кое-что из этого ответа: в Unix, если файл открыт и удален ( rm), он еще не удален. Он будет существовать на диске и все еще может быть прочитан всеми открытыми процессами. Он будет удален только тогда, когда количество жестких ссылок достигнет нуля, а число прецессов с открытым файлом достигнет нуля.
Ctrl-Alt-Delor
@ Патрик: installУтилита специально небезопасна! Он перезаписывает целевой файл на месте, а не заменяет его атомарно. mv(с источником и папкой в ​​одном каталоге, источником обычно является временный файл) - это единственный безопасный способ установки файлов.
R .. GitHub ОСТАНОВИТЬ ЛЬДА
1
@ Патрик, насколько мне известно strace, installв GNU coreutils отсоединяет целевой файл, а затем копирует новый на его место. Это означает, что есть короткое окно, в течение которого файл является частичным. Это не устанавливает файл атомарно на месте с переименованием.
ilkkachu
3

Файлы не будут "правильно удалены", если они не связаны, пока они все еще открыты. Когда они закрыты, используемое ими дисковое пространство снова будет считаться «свободным». Это относится и к текущим приложениям и их общим библиотекам.

Единственное, что я мог увидеть сбой, - это если программа использовала dlopen()для загрузки разделяемую библиотеку по требованию или если программе приходилось обращаться к другим файлам по требованию, таким как словари, файлы тем или другие файлы, которые внезапно исчезали.

Для иллюстрации: запуск vimв одном сеансе оболочки при удалении установки vimв другом сеансе оболочки не «повредит» и не завершит текущий запущенный vimсеанс. Но некоторые вещи начнут давать сбой, например, проверка орфографии, которая требует vimоткрытия файлов при установке.

Кусалананда
источник