Vim kann Dateiberechtigungen brechen?

Vim kann Dateiberechtigungen brechen?

Ich habe neulich Vim wie üblich verwendet, als mir etwas Merkwürdiges auffiel. Folgendes habe ich getan:

~$ touch testfile
~$ ls -l | grep testfile
-rw-r--r-- 1 username groupname 0 Jul 23 10:00 testfile
~$ vim testfile

Dann habe ich eine Änderung vorgenommen, gespeichert und mit beendet :wq. Ziemlich normal. Dann jedoch:

~$ sudo chown root:root testfile
~$ sudo chmod 644 testfile
~$ sudo -k
~$ ls -l | grep testfile
-rw-r--r-- root root 0 Jul 23 10:02 testfile
~$ vim testfile

Root sollte also Schreib-/Lesezugriff haben und alle anderen sollten nur Lesezugriff haben. Bearbeiten Sie die Datei, versuchen Sie zu speichern – das geht nicht. Super, funktioniert wie vorgesehen. Wenn Sie jedoch mit speichern :w!, ändert vim den Dateibesitz irgendwie zurück zu Benutzername:Benutzergruppe und die Datei wird gespeichert. Auch wenn Sie dies tun:

~$ sudo chmod 444 testfile
~$ sudo -k
~$ ls -l | grep testfile
-r--r--r-- 1 root root 0 Jul 23 10:06 testfile
~$ vim testfile

Du kannstTrotzdemüberschreiben mit :w!! Was ist los? Wie kann vim die Gesetze zu Dateieigentum und -berechtigungen auf diese Weise verletzen? Ich habe mir die Hilfeseite von vim angesehen :help :wund Folgendes gefunden:

:w[rite]! [++opt]    Like ":write", but forcefully write when 'readonly' is set or there is another reason why writing was refused.
                     Note: This may change the permission and ownership of the file and break (symbolic) links. Add the 'W' flage to 'cpoptions' to avoid this.

Ich konnte bisher nicht in eine Datei in Vim schreiben, obwohl ich das nicht sollte, daher liegt der eigentliche Kern meiner Frage wohl darin, wie ich eine Datei für Vim uneditierbar machen kann und warum dies nicht, wie ich erwarten würde, auf den Dateisystemberechtigungen basiert und welchen Mechanismus Vim zum Bearbeiten der Datei verwendet, den andere Editoren (gedit, nano) nicht verwenden können.

BEARBEITEN: Der Computer, auf dem ich dies ausprobiert habe, verwendet den Linux-Kernel 3.15.5-2-ARCH. Die Versionsnummer von Vim ist 7.4.373-1 und wurde von mir installiert pacman– ich habe es nicht von Grund auf mit irgendwelchen speziellen Optionen kompiliert.

Antwort1

Ich sehe, dass Ihr aktueller Pfad ~das Stammverzeichnis Ihres Benutzers ist. Sie sollten Schreibberechtigung für dieses Verzeichnis haben.

Betrachten Sie es anders: Wenn Sie Lese- und Schreibberechtigungen für das Verzeichnis haben, was hindert Sie dann daran, die Datei zu kopieren, die alte zu löschen und die neue mit anderen Berechtigungen umzubenennen?

Dies ist genau, was vim macht!


Wenn Sie vim beispielsweise unter strace ausführen:

open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = -1 EACCES (Permission denied)
lstat("testfile", {st_mode=S_IFREG|0644, st_size=10, ...}) = 0
getuid()                                = 1000
unlink("testfile")                      = 0
open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
write(3, "ffjidfjds\n", 10)             = 10
fsync(3)                                = 0
close(3)                                = 0
chmod("testfile", 0644)                 = 0

Anhand dieses Protokolls kann ich den folgenden Vorgang erraten:

Einige frühere Berechtigungsprüfungen (und chownVersuche usw.) werden der Kürze halber weggelassen.

  1. openVersuch, die Datei zum Schreiben zu öffnen (fehlgeschlagen: Berechtigung verweigert)
  2. lstatÜberprüfen Sie den Besitzer der Datei
  3. getuuidÜberprüfen Sie die aktuelle Benutzer-ID, um festzustellen, ob sie mit dem Dateibesitzer übereinstimmt.
  4. unlinkLöschen Sie die Datei (dies ist erlaubt, da Schreibberechtigung für das Verzeichnis besteht)
  5. openErstellen Sie eine neue Datei mit demselben Namen
  6. writeDer Dateiinhalt (vorher gelesen, ich habe Kauderwelsch eingetippt)
  7. fsyncDie Datei auf die Festplatte schreiben (nicht wirklich wichtig)
  8. close
  9. chmodÄndern Sie die Berechtigungen der neuen Datei so, dass sie denen der alten ähneln – sie hat jetzt nur zufällig einen neuen Besitzer.

verwandte Informationen