Vim può violare i permessi dei file?


8

Stavo usando Vim l'altro giorno come al solito, quando ho notato qualcosa di strano. Ecco cosa ho fatto:

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

Quindi ho apportato una modifica, ho salvato e ho chiuso :wq. Abbastanza normale Quindi, tuttavia:

~$ 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

Quindi root dovrebbe avere accesso r / w e tutti gli altri dovrebbero solo leggere. Modifica il file, prova a salvare - non puoi. Fantastico, funziona come previsto. Tuttavia, se si salva con :w!, vim in qualche modo modifica la proprietà del file in nome utente: gruppo utenti e il file viene salvato. Anche se lo fai:

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

Puoi ancora sovrascrivere con :w!! Che cosa sta succedendo? Come può vim infrangere le leggi sulla proprietà e l'autorizzazione dei file in questo modo? Ho guardato la pagina di aiuto in vim dicendo :help :we ho trovato questo:

: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.

Non sono stato in grado di scrivere su un file in VIM in precedenza quando non avrei dovuto, quindi immagino che il vero cuore della mia domanda sia, come posso rendere un file non modificabile da VIM e perché non è basato su file autorizzazioni di sistema, come mi aspetterei, e quale meccanismo utilizza Vim per modificare il file che altri editor (gedit, nano) non possono usare?

EDIT: Il computer su cui ho provato questo sta usando il kernel Linux 3.15.5-2-ARCH. Il numero di versione di Vim è 7.4.373-1, ed è quello installato da pacman- Non l'ho compilato da zero con nessuna opzione speciale.


Non riesco a riprodurre il problema, a meno che non faccia qualche trucco come descritto qui
Davyzhu,

Ho appena provato di nuovo usando i comandi nella domanda, ed è successo allo stesso modo. Modificherò la domanda per aggiungere dettagli sul mio computer, anche se sembra che questo potrebbe dipendere dalla piattaforma.
circa il

Il mio primo sospetto è che ti è permesso cambiare la proprietà dei file in una directory a cui hai accesso in scrittura. Ma sembra che non sia così . CAP_CHOWNè necessario chiamare chown(2). A proposito, posso riprodurre su Debian, con vim 7.4.
Bob,

Risposte:


10

Vedo che il tuo percorso attuale è ~la home directory del tuo utente. È necessario disporre delle autorizzazioni di scrittura per quella directory.

Pensala in un altro modo: se hai le autorizzazioni di lettura e scrittura nella directory, cosa ti impedisce di copiare il file, eliminare quello vecchio e rinominare quello nuovo con autorizzazioni diverse?

Questo è esattamente ciò che fa Vim!


Se esegui vim sotto strace, ad esempio:

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

Sulla base di questo registro, posso indovinare il seguente processo:

Alcuni controlli di autorizzazione precedenti (e chowntentativi, ecc.) Sono stati omessi per brevità.

  1. open Tentativo di aprire il file per la scrittura (errore: autorizzazione negata)
  2. lstat Controlla il proprietario del file
  3. getuuid Controlla l'ID utente corrente per vedere se corrispondono al proprietario del file
  4. unlink Elimina il file (questo è consentito perché autorizzazione di scrittura nella directory)
  5. open Crea un nuovo file con lo stesso nome
  6. write Il contenuto del file (leggi prima, ho digitato un po 'di incomprensibile)
  7. fsync Svuota il file su disco (non molto importante)
  8. close
  9. chmod Modifica le autorizzazioni del nuovo file in modo che assomiglino a quello precedente: adesso sembra che abbia un nuovo proprietario.

Ok grazie. Sono contento di averlo capito. Quindi se non ho i permessi di scrittura sulla directory, non sarò in grado di usare :w!, il che ha senso.
circa il

Inoltre, le informazioni sullo strace sono davvero utili - ora ho un altro strumento per le mie indagini in futuro.
circa il

1
@zrneely Un consiglio per strace: usare l' -oopzione per scrivere l'output in un file; altrimenti si scontra con viml'output di. Per quanto riguarda i permessi di scrittura, io non lo vedo il controllo delle autorizzazioni di directory con stat, ma non tentare di creare un file (nome 4913, sembra casuale) nella directory corrente e quindi eliminarlo.
Bob,

Sembra che in 4913realtà sia solo il nome che prova e il suo scopo è verificare se dispone di autorizzazioni sufficienti per farlo. Vedi: bugzilla.redhat.com/show_bug.cgi?id=427711#c6 e groups.google.com/forum/#!topic/vim_dev/sppdpElxY44
Bob
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.