In che modo vim ruba i file di proprietà di root?


39

Testimoniare quanto segue:

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

In qualche modo vim ha preso questo file di proprietà di root e lo ha cambiato in un file di proprietà dell'utente!

Questo sembra funzionare solo se l'utente possiede la directory, ma sembra comunque che non dovrebbe essere possibile. Qualcuno può spiegare come è fatto?

Risposte:


51

Sei glenil proprietario della directory (vedi il .file nella tua scheda). Una directory è solo un elenco di file e hai il permesso di modificare questo elenco (ad es. Aggiungere file, rimuovere file, cambiare proprietà per renderlo tuo di nuovo, ecc.). Potrebbe non essere possibile modificare direttamente il contenuto del file, ma è possibile leggere e scollegare (rimuovere) il file nel suo insieme e aggiungere nuovi file successivamente. 1 Solo testimoniando il prima e il dopo, questo può sembrare che il file sia stato modificato.

Vim usa i file di scambio e sposta i file sott'acqua, quindi questo spiega perché sembra scrivere nello stesso file che hai nella shell, ma non è la stessa cosa. 2

Quindi, ciò che fa Vim, si riduce a questo:

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 Questa è una differenza importante nella gestione delle autorizzazioni dei file tra Windows e Unices. In Windows, di solito non è possibile rimuovere file per i quali non si dispone dell'autorizzazione di scrittura.

2 aggiornamento: come notato nei commenti, Vim non lo fa in questo modo per cambiare la proprietà, poiché il numero di inode sul tempfile non cambia (comaring ls -liprima e dopo). Usando stracepossiamo vedere esattamente cosa vimfa. La parte interessante è qui:

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

Ciò mostra che scollega solo , ma non chiude il descrittore di file temp. Piuttosto sovrascrive solo i suoi contenuti ( more text bla\nnel mio caso). Immagino che questo spieghi perché il numero di inode non cambia.


3
FWIW puoi verificare che ciò avvenga eseguendo ls -ilprima e dopo ... se tempil numero di inode è cambiato, sai che è un file diverso con lo stesso nome.
Inutile

3
Si potrebbe aggiungere che rm in realtà non rimuove il file, ma rimuove semplicemente un collegamento al file e il file non viene eliminato prima che il numero di collegamenti diminuisca a 0. rm rimuove semplicemente la voce al file nella directory. Se root ha un altro collegamento (hard link) al file in un'altra directory, l'utente non può rimuovere il file.
Gerrit,

1
@Inutile ho provato, e il numero non è cambiato nonostante il proprietario e il timestamp siano cambiati!
Amyassin,

1
@amyassin Hai ragione! Ho aggiornato la mia risposta con un estratto di strazia che lo spiega.
Gertvdijk,

1
A parte la nota sulle autorizzazioni Windows vs Unix, se si desidera un comportamento simile a Windows in Unix, è possibile creare una directory di proprietà di root (o di un altro utente che dovrebbe avere autorizzazioni universali di rimozione / rinomina / etc) e impostare l'adesione bit nella directory. Quindi gli utenti saranno in grado di eliminare solo i propri file.
Matthew Crumley,

16

prima:

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

dopo:

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

Il vim non supera la barriera di autorizzazione. Dai un'occhiata alle informazioni sui file elencate con attenzione, quindi potresti scoprire che vim ha effettivamente eliminato il file originale (perché hai l'autorizzazione per rimuovere il file anche se non puoi modificarne il contenuto), quindi hai creato un tuo nuovo file ( vedere il proprietario non è più 'root').

E mentre stai modificando il file originale in vim, avverte che stai cambiando un file di sola lettura. Quindi, quando si digita il comando :wq!(forzare l'operazione), ciò che può fare solo vim è eliminare il file esistente e creare un nuovo file con lo stesso nome.

Spero che sia d'aiuto.


1

Usa l' -iopzione di lsper vedere il numero di inode, che è un identificatore univoco (all'interno del filesystem) di un file o di un altro oggetto.

Vedrai che il file è stato sostituito con un oggetto diverso: il numero di inode probabilmente cambierà.

Vedere lo stesso numero di inode non è una prova di nulla: un numero di inode può essere riciclato. Se rimuoviamo l'ultimo collegamento a un file e quindi creiamo un nuovo file, potremmo ottenerne uno con lo stesso numero di inode. Ma ciò non può accadere se il vecchio file viene rimosso dopo la creazione di quello nuovo. Es mv file file.tmp; touch file; rm file.tmp. Ho il sospetto che Vim effettivamente fa qualcosa di analogo a questo echo new_content > tmpfile; mv tmpfile file. L' mvoperazione si tradurrà in una renamechiamata di sistema, quindi l'assegnazione dei numeri di inode dipende da come il filesystem implementa una ridenominazione che scollega una destinazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.