Gibt es einen Mechanismus, der Anwendungen während des Bibliotheks-Upgrades schützt?

10

Wenn der Benutzer an einer dynamisch verknüpften Anwendung arbeitet und das System aktualisiert wird, gibt es einen Schutzmechanismus, der eine Beschädigung der Anwendung verhindert?

Oder liegt es an der Bewerbung?

sevo
quelle
Denken Sie daran, ein Linux-Buch darüber zu lesen, wie Sie ln -sfbeim Austauschen von Bibliotheken vorgehen sollten , da -fSie damit das vorhandene Ziel der symbolischen Verknüpfung mit einer neuen "überschreiben" konnten, ohne dass es jemals "beschädigt" wurde (im Gegensatz zu einer Folge, bei der Sie rmgefolgt sind) a ln -s). Vor dem Befehl zeigte library.so auf die alte Version, z. library.so.4 ... nach dem Befehl, es ist einfach zu spitz library.so.5 (oder was auch immer) statt - ohne jemals nicht auf eine gültige Bibliothek zeigt.
Baard Kopperud

Antworten:

16

Wie von @Kusalananda erwähnt, werden Upgrades normalerweise durchgeführt, indem die alte Datei entfernt und eine neue mit demselben Namen erstellt wird. Dadurch wird tatsächlich eine neue Datei mit einem neuen Inode erstellt, sodass das System die alte Datei verwenden kann, solange sie geöffnet ist.

Als vereinfachtes Beispiel Dinge wie

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

erstellt eine logisch neue Datei und funktioniert, obwohl sie catmöglicherweise ausgeführt wird. Gleiches gilt für Bibliotheken. (Das Obige ist ein Beispiel, keine robuste Methode zum Aktualisieren einer Datei in der realen Welt.)


Jemand könnte versuchen, die Binärdatei an Ort und Stelle zu ändern, anstatt eine neue mit demselben Namen zu erstellen. In diesem Fall verhindert zumindest Linux tatsächlich, dass Änderungen an einer verwendeten ausführbaren Datei vorgenommen werden:

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

Dies scheint jedoch bei dynamisch geladenen Bibliotheken nicht zu funktionieren ...

Ich habe eine Kopie libc.so.6zum Testen erstellt und sie während des Gebrauchs mit Nullen gefüllt:

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

(In der Zwischenzeit in einem anderen Fenster, nach dem foo, vor dem Segfault)

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

Es gibt wirklich nichts, was das Programm selbst dagegen tun könnte, da ich seinen Code effektiv online bearbeitet habe.

(Dies wäre wahrscheinlich systemabhängig. Ich habe es unter Debian Jessie 8.5, Linux 3.16.7-ckt25-2 + deb8u3 getestet. Insbesondere IIRC-Windows-Systeme sind noch aggressiver, wenn es darum geht, zu verhindern, dass verwendete Dateien geändert werden.)


Ich denke, die Antwort ist, dass Upgrades normalerweise so durchgeführt werden, dass Probleme vermieden werden. Dies wird durch die Interna des Dateisystems unterstützt. Aber (unter Linux) scheint es keine Schutzmaßnahmen gegen die tatsächliche Beschädigung dynamischer Bibliotheken zu geben.

ilkkachu
quelle
Das installDienstprogramm wird häufig für solche Dinge verwendet. Sie müssen die Zieldatei nicht explizit rmangeben. Außerdem werden die Berechtigungen der vorhandenen Datei beibehalten, ein Backup erstellt, ein neuer Modus festgelegt usw. Verwendungsbeispiel:install /new/version/of/cat /bin/cat
Patrick
Sicher. Das rm+ cpwar als Beispiel gedacht. Es kann auch sinnvoll sein, die neue Datei atomar mit einer Umbenennung zu platzieren, um ein kurzes Fenster zu vermeiden, in dem keine der beiden Versionen verfügbar ist. (Obwohl GNU installdas nicht einmal zu tun scheint, hmpf.)
ilkkachu
2
Ich möchte etwas klarstellen, das in dieser Antwort enthalten ist: Wenn unter Unixes eine Datei geöffnet und entfernt ( rm) ist, wird sie noch nicht gelöscht. Es wird auf der Festplatte vorhanden sein und kann weiterhin von allen Prozessen gelesen werden, bei denen es geöffnet ist. Es wird nur gelöscht, wenn die Anzahl der festen Verbindungen Null erreicht UND die Anzahl der Vorgänge bei geöffneter Datei Null erreicht.
Strg-Alt-Delor
@Patrick: Das installDienstprogramm ist speziell unsicher! Die Zieldatei wird überschrieben, anstatt sie atomar zu ersetzen. mv(mit Quelle und Ziel im selben Verzeichnis, Quelle normalerweise eine temporäre Datei) ist der einzig sichere Weg, um Dateien zu installieren.
R .. GitHub STOP HELPING ICE
1
@Patrick hebt, soweit ich weiß strace, installin GNU Coreutils die Verknüpfung der Zieldatei auf und kopiert dann eine neue an ihre Stelle. Dies bedeutet, dass es ein kurzes Fenster gibt, in dem die Datei teilweise ist. Die Datei wird bei einer Umbenennung nicht atomar festgelegt.
Ilkkachu
3

Dateien werden nicht "ordnungsgemäß gelöscht", wenn sie nicht verbunden sind, während sie noch geöffnet sind. Wenn sie geschlossen sind, wird der von ihnen verwendete Speicherplatz wieder als "frei" betrachtet. Dies gilt auch für aktuell ausgeführte Anwendungen und deren gemeinsam genutzte Bibliotheken.

Das einzige, was ich als fehlerhaft ansehen konnte, war, wenn ein Programm dlopen()zum Laden einer gemeinsam genutzten Bibliothek bei Bedarf verwendet wurde oder wenn das Programm bei Bedarf auf andere Dateien wie Wörterbücher, Themendateien oder andere Dateien zugreifen musste, die plötzlich verschwanden.

Zur Veranschaulichung: Das Ausführen vimin einer Shell-Sitzung beim Löschen der Installation vimin einer anderen Shell-Sitzung wird die aktuell ausgeführte vimSitzung nicht "beschädigen" oder beenden . Einige Dinge schlagen jedoch fehl, beispielsweise die Rechtschreibprüfung, bei der vimDateien in der Installation geöffnet werden müssen.

Kusalananda
quelle