Wenn ich versuche , eine binäre Datei zu überschreiben , die derzeit gestartet wird, cp
nicht überschrieben werden , aber es ist möglich, rm
es 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?
Antworten:
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 technisch
rm
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.
quelle
/proc/*/fd
Sie diese Option , um darauf zuzugreifen, und optional linkat () , um dem Dateisystem einen neuen Link hinzuzufügen.linkat()
. (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ührenlinkat
und zu beweisen, dass es nicht funktioniert, auch als root: /