Comment vim dérobe-t-il les files racine?

Témoin ce qui suit:

sh-3.2$ mkdir testcase sh-3.2$ cd testcase sh-3.2$ sudo touch temp sh-3.2$ ls -al total 0 drwxr-xr-x 3 glen staff 102 19 Dec 12:38 . drwxr-xr-x 12 glen staff 408 19 Dec 12:38 .. -rw-r--r-- 1 root staff 0 19 Dec 12:38 temp sh-3.2$ echo nope > temp sh: temp: Permission denied sh-3.2$ vim temp # inside vim itheivery # press [ESC] :wq! # vim exits sh-3.2$ ls -al total 8 drwxr-xr-x 3 glen staff 102 19 Dec 12:38 . drwxr-xr-x 12 glen staff 408 19 Dec 12:38 .. -rw-r--r-- 1 glen staff 7 19 Dec 12:38 temp 

D'une certaine façon, vim a pris ce file appartenant à la racine, et l'a changé en un file appartenant à l'user!

Cela ne semble fonctionner que si l'user possède le directory – mais il a toujours l'printing que cela ne devrait pas être possible. Quelqu'un peut-il expliquer comment cela se fait?

Vous, glen , êtes le propriétaire du directory (voir le file de votre list). Un directory est juste une list de files et vous avez la permission de modifier cette list (par exemple, append des files, supprimer des files, changer de propriétaire pour le faire à nouveau, etc.). Vous ne pouvez pas modifier le contenu du file directement, mais vous pouvez lire et dissocier (supprimer) le file dans son set et append de nouveaux files par la suite. 1 Seulement témoin de l'avant et après, cela peut ressembler au file a été modifié.

Vim utilise des files d'échange et déplace des files sous l'eau, ce qui explique pourquoi il semble écrire le même file que vous dans votre shell, mais ce n'est pas la même chose. 2

Donc, ce que Vim fait, cela se résume à ceci:

 cat temp > .temp.swp # copy file by contents into a new glen-owned file echo nope >> .temp.swp # or other command to alter the new file rm temp && mv .temp.swp temp # move temporary swap file back 

1 Il s'agit d'une différence importante dans la gestion des permissions de files entre Windows et Unices. Dans Windows, il n'est généralement pas possible de supprimer des files pour lesquels vous n'avez pas l'autorisation d'écriture.

2 mise à jour: comme indiqué dans les commentaires, Vim ne le fait pas de la même façon pour changer la propriété, car le numéro d'inode sur le file temp ne change pas (en comparant ls -li avant et après). En utilisant strace nous pouvons voir exactement ce que vim fait. La partie intéressante est ici:

 open("temp", O_WRONLY|O_CREAT|O_TRUNC, 0664) = -1 EACCES (Permission denied) unlink("temp") = 0 open("temp", O_WRONLY|O_CREAT|O_TRUNC, 0664) = 4 write(4, "more text bla\n", 14) = 14 close(4) = 0 chmod("temp", 0664) = 0 

Cela montre qu'il ne se lie que , mais ne ferme pas le descripteur de file à temp . Il écrase plutôt tout son contenu ( more text bla\n dans mon cas). Je suppose que cela explique pourquoi le numéro d'inode ne change pas.

avant:

-rw-r--r-- 1 root staff 0 19 Dec 12:38 temp

après:

-rw-r--r-- 1 glen staff 7 19 Dec 12:38 temp

Le vim ne franchit pas la barrière des permissions. Jetez simplement un oeil sur les informations du file listées avec soin, puis vous verrez que vim a effectivement supprimé le file original (car vous avez l'autorisation de supprimer le file mais vous ne pouvez pas en changer le contenu) puis créé un nouveau file que vous possédez voir le propriétaire n'est plus «root»).

Et pendant que vous modifiez le file d'origine dans vim, il avertit que vous modifiez un file en lecture seule. Donc, lorsque vous tapez la command :wq! (force l'opération), ce que vim ne peut faire que de supprimer le file existant et créer un nouveau file qui a le même nom.

J'espère que cela pourra aider.

Utilisez l'option -i de ls pour voir le numéro d'inode, qui est un identifiant unique (dans le système de files) d'un file ou d'un autre object.

Vous verrez que le file a été remplacé par un object différent: le numéro d'inode changera probablement.

Voir le même numéro d'inode ne prouve rien: un numéro d'inode peut être recykey. Si nous supprimons le dernier lien vers un file, puis que nous créons un nouveau file, nous pourrions en get un avec le même numéro d'inode. Mais cela ne peut pas se produire si l'ancien file est supprimé après la création du nouveau file. Par exemple, mv file file.tmp; touch file; rm file.tmp mv file file.tmp; touch file; rm file.tmp mv file file.tmp; touch file; rm file.tmp . Je pense que Vim fait quelque chose d'analogue à cet echo new_content > tmpfile; mv tmpfile file echo new_content > tmpfile; mv tmpfile file . L'opération mv se traduira par un rename appel système, de sorte que l'atsortingbution des numéros d'inode dépend de la manière dont le système de files implémente un changement de nom qui dissocie une destination.