cp overwrite vs rm dann cp

18

Wenn ich versuche , eine binäre Datei zu überschreiben , die derzeit gestartet wird, cpnicht überschrieben werden , aber es ist möglich, rmes dann cp. Beispielsweise:

user@poste:~$ cp binaryFile /tmp
user@poste:~$ sudo cp /tmp/binaryFile binaryFile 
[sudo] password for user:
cp: cannot create regular file `binaryFile`: Text file busy
user@poste:~$ sudo rm binaryFile 
user@poste:~$ sudo cp /tmp/binaryFile  binaryFile 
user@poste:~$ file binaryFile 
binaryFile : ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x7ce005d9eb50e2574246b6a881e625802f7e49f2, not stripped

Irgendeine Idee warum?

M4rty
quelle
2
Interessanter kleiner Thread, sollte aber unter Unix / Linux.SE IMO sein.
Underscore_d

Antworten:

41

Im ersten Fall versuchen Sie, den Inhalt einer Datei zu überschreiben, die derzeit als Programm ausgeführt wird. Linux lässt das nicht zu - wenn ja, würden Sie den Code überschreiben, während das Betriebssystem ihn ausführte. Der erste Unterschied würde das Programm zum Absturz bringen oder zu Fehlfunktionen führen.

Im zweiten Fall ändern Sie jedoch nicht den Inhalt der alten Datei, sondern erstellen stattdessen eine neue Datei, während die alte Datei nur den Dateinamen verliert, den Inhalt jedoch unberührt lässt.

(Denken Sie daran, dass Dateien technischrm nicht gelöscht werden, sondern nur Verzeichnisverknüpfungen entfernt werden - ähnlich wie beim Hinzufügen weiterer Verknüpfungen zu derselben Datei. Nur wenn eine Datei keine Verknüpfungen und keine geöffneten Dateiverweise enthält, wird sie automatisch gelöscht.)ln

Das System verweist auf in Verwendung befindliche Dateien anhand ihres Inodes, sodass es keine Rolle spielt, ob sie denselben Dateinamen haben - es ist immer noch die alte Datei, die vom System geöffnet bleibt, und obwohl sie keine Links mehr enthält, wird sie nur gelöscht Sobald alle Programme es schließen.

Grawity
quelle
7
Ein weiterer Trick, der häufig mit der gleichen Logik verwendet wird: Öffnen Sie eine (temporäre) Datei in Ihrer Software und löschen Sie sie sofort, ohne die Datei vorher zu schließen. Ihr Programm kann es weiterhin so verwenden, wie es möchte, und wenn Ihr Programm es schließt (gesteuert) oder vergisst, es zu schließen (z. B. wenn Ihr Programm ohne Bereinigung abgestürzt ist), wird es automatisch vom Betriebssystem entfernt. (Programmende, egal wie das passiert ist, veröffentlicht alle Verweise auf Programm musste auf die Datei.)
Tonny
2
Das ist auch der Grund, warum beim Löschen einer Protokolldatei eines laufenden Prozesses der Befehl df die korrigierte Größe erst dann
zurückgibt,
Gibt es eine Möglichkeit für ein externes Programm (mit Root-Berechtigungen), ein neues Handle für diese baumelnde Inode zu finden und zu erstellen? Ich stelle mir vor, dass es Programme gibt, die dies als "Sicherheitsmerkmal" verwenden. Es ist also interessant, die ganze Geschichte zu verstehen.
BenPen
3
@BenPen: Unter Linux, yes - verwenden /proc/*/fdSie diese Option , um darauf zuzugreifen, und optional linkat () , um dem Dateisystem einen neuen Link hinzuzufügen.
Grawity
3
@BenPen und grawity: Tatsächlich können Sie einen Inode aus Sicherheitsgründen nicht wieder in die Verzeichnisstruktur einbinden, wenn er keine Links enthält, auch nicht mitlinkat() . (Ausnahme von dieser Regel: es sei denn , es erstellt wurde , open(O_TMPFILE)damit es begann mit Null - Links.) Wenn Sie versuchen, linkat()kehrt ENOENT, sogar als Root. Siehe meine Antwort auf diese Frage für ein Perl-Skript, um tatsächlich auszuführen linkatund zu beweisen, dass es nicht funktioniert, auch als root: /
Peter Cordes