Чи існує механізм, який захищає програми під час оновлення бібліотеки?


10

Якщо користувач працює над додатком, який динамічно пов'язаний, а система оновлюється, чи існує якийсь механізм захисту, який запобігає пошкодженню програми?

Або це залежить від застосування?


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

Відповіді:


16

Як згадував @Kusalananda, зазвичай оновлення виконується шляхом видалення старого файлу та створення нового з тим самим іменем. Це фактично створить новий файл з новим inode, залишивши систему вільною для використання старого, поки він відкритий.

Як спрощений приклад, такі речі, як

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. Зокрема, системи IIRC Windows ще більш агресивно ставляться до запобігання модифікації файлів під час використання.)


Тому я думаю, що відповідь полягає в тому, що оновлення, як правило, робиться таким чином, щоб уникнути будь-яких проблем, і в цьому допомагають внутрішні файлові системи. Але (в Linux), схоже, немає жодних гарантій проти фактично пошкодження динамічних бібліотек.


installУтиліта зазвичай використовується для речей , як це. Не потрібно явно отримувати rmцільовий файл. Крім того, він зберігає дозволи на існуючий файл, може створити резервну копію, встановити новий режим тощо. Приклад використання:install /new/version/of/cat /bin/cat
Патрік

Звичайно. У якості прикладу було позначено rm+ cp. Можливо, також було б розумно розмістити новий файл на місці атомістично з перейменуванням, уникаючи короткого вікна, в якому немає жодної версії. (Хоча GNU installнавіть не здається цього робити, hmpf.)
ilkkachu

2
Я хотів би зрозуміти щось, що є у цій відповіді: У Unixes, якщо файл відкритий, а вилучений ( rm), він ще не видалений. Він буде існувати на диску і все ще може бути прочитаний усіма процесами, у яких він відкритий. Він буде видалений лише тоді, коли його кількість жорстких посилань досягне нуля І кількість прецесій з відкритим файлом досягне нуля.
ctrl-alt-delor

@Patrick: installУтиліта спеціально небезпечна! Він замінює цільовий файл на місці, а не замінює його атомно. mv(з джерелом і dest в одному каталозі, джерело, як правило, тимчасовий файл) - єдиний безпечний спосіб встановлення файлів.
R .. GitHub ЗАСТАНОВИТИ ДІЯ

1
@Patrick, наскільки я straceрозповідаю, installв GNU coreutils від’єднує цільовий файл і потім копіює новий на своє місце. Що означає, що є коротке вікно, під час якого файл є частковим. Він не встановлює файл атомно на перейменування.
ilkkachu

3

Файли не будуть "належним чином видалені", якщо вони від’єднані, поки вони все ще відкриваються. Коли вони закриті, дисковий простір, який вони використовували, знову буде вважатися "вільним". Це стосується також запущених додатків та їх спільних бібліотек.

Єдине, що я можу побачити, як не вдалося, було б, якщо програма, що використовується dlopen()для завантаження спільної бібліотеки на вимогу, або якщо програма мала отримати доступ до інших файлів на вимогу, таких як словники, теми тем чи інші файли, які раптово зникли.

Для ілюстрації: Запуск vimв одному сеансі оболонки під час видалення інсталяції vimв іншому сеансі оболонки не «пошкоджується» або припиняється поточно запущений vimсеанс. Але деякі речі почнуть виходити з ладу, як, наприклад, перевірка орфографії, яка вимагає vimвідкриття файлів при її встановленні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.