Vi può scrivere su file nonostante il file sia di sola lettura


12

L'esempio seguente mostra come creare un file con solo autorizzazioni di lettura. Come possiamo vedere, quando provo a scrivere in questo file usando il comando echo ottengo, Permission denied.

Ma perché, nel caso in cui utilizziamo vi, non otteniamo Permission denied? Come si può vedere qui, possiamo scrivere sul file anche se il file è di sola lettura.

Cosa sta succedendo qui? È un bug vi?

[admin@madona-machine1 ~]$ touch test-file
[admin@madona-machine1 ~]$ ls -ltr
total 0
-rw-r--r-- 1 admin admin 0 Apr 13 07:32 test-file
[admin@madona-machine1 ~]$ chmod -w  test-file
[admin@madona-machine1 ~]$ ls -ltr
total 0
-r--r--r-- 1 admin admin 0 Apr 13 07:32 test-file
[admin@madona-machine1 ~]$ echo try_to_write > test-file
-bash: test-file: Permission denied
[admin@madona-machine1 ~]$ vi test-file

I am good singer,

 ~
 ~
 ~
 ~
 ~
 ~
 ~                                                
   "test-file" 1L, 4C written

1
A proposito, c'è un sito beta SE per questo - vi.stackexchange.com
Raystafarian

Risposte:


28

Nota : per motivi di licenza legacy, la maggior parte delle distribuzioni GNU / Linux non include il programma vi originale come scritto da Bill Joy. Al contrario, il comando vi viene fornito eseguendo Vim in modalità vi-compatibilità. La seguente risposta si basa sull'esecuzione di Vim con la sua modalità di compatibilità vi.

Modifica di un file di sola lettura

Vim avvisa l'utente se ne modificano il buffer di un file di sola lettura, W10: Warning: Changing a readonly file. Se i tentativi di utente iscritto a questo file, ottengono il seguente messaggio di errore, 'readonly' option is set (add ! to override).

Quando la directory principale è scrivibile dall'utente Vim

Vim, essendo utile, fa sapere all'utente che può insistere con forza sulla scrittura aggiungendo un punto esclamativo !al wcomando. Se viene utilizzata questa versione forzata del comando di scrittura, Vim elimina il file originale (se si utilizza Vim con l' backupopzione di solo Vim impostata, il file originale viene effettivamente rinominato per essere uguale al file di backup). Quindi apre (crea) un nuovo file con lo stesso nome dell'originale e scrive il contenuto del suo buffer su questo nuovo file. Questo può essere osservato controllando l' inode del file prima e dopo aver eseguito Vim:

$ ls -l --inode t

131529 -r--r--r-- 1 anthony anthony 0 Apr 13 09:23 t

$ vi t
$ ls -l --inode t

131649 -r--r--r-- 1 anthony anthony 4 Apr 13 09:23 t

Nota: ciò può anche modificare l'autorizzazione e la proprietà del file e interrompere i collegamenti (simbolici), ad esempio, se il file originale era di proprietà di un altro utente, il nuovo file sarebbe di proprietà dell'utente che esegue Vim.

Un processo può farlo solo se dispone dell'autorizzazione di scrittura per la directory padre del file. In generale, per garantire che un programma non possa modificare un file, è necessario proteggere le autorizzazioni sia del file stesso sia della directory principale.

Quando la directory principale non è scrivibile dall'utente Vim

Tuttavia, anche in questo caso, Vim fa ancora del suo meglio per aiutare l'utente insistente a sovrascrivere il file. Se l'utente Vim è proprietario del file, Vim può aggirare la restrizione della directory principale di sola lettura modificando temporaneamente l'autorizzazione del file (utilizzando la chmodchiamata di sistema), scrivendo il buffer nel file, chiudendo il file e quindi cambiando il permessi indietro. Ecco un estratto delle chiamate di sistema effettuate durante l'esecuzione VI attraverso strace, strace -o ../vi.trace vi t:

getuid()                                = 501
chmod("t", 0100644)                     = 0
open("t", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "I am good singer,\n", 18)     = 18
fsync(4)                                = 0
close(4)                                = 0
chmod("t", 0100444)                     = 0

Nota: ciò non accade se l'utente Vim sta modificando un file di cui non possiede la proprietà in quanto Vim non sarà in grado di modificare le autorizzazioni del file.

appendice

Per essere veramente certi che un file non può essere modificato (su un sistema GNU / Linux), esegui il chattrcomando come superutente:

sudo chattr +i filename

Da man chattr:

Un file con l'attributo 'i' non può essere modificato: non può essere cancellato o rinominato, non è possibile creare alcun collegamento a questo file e nessun dato può essere scritto nel file. Solo il superutente o un processo che possiede la capacità CAP_LINUX_IMMUTABLE può impostare o cancellare questo attributo.


2
Fumo santo, quello era accurato!
Camille Goudeseune,

4
@CamilleGoudeseune Dopo aver pubblicato la prima versione della mia risposta, ho fatto alcuni esperimenti e ho finito per passare circa un'ora a correre Vim attraverso la sequenza per vedere cosa stava facendo dietro le quinte in diverse situazioni (diverse permutazioni di autorizzazioni e proprietà di entrambi i file e directory principale). A volte vengo portato via, ma una volta pubblicata una risposta, volevo essere sicuro che ciò che stavo dicendo fosse corretto.
Anthony Geoghegan,

5

La maggior parte se non tutte le viimplementazioni impediscono di scrivere il file se si utilizza un normale salvataggio comando come sia ZZ, :w, :wqo :x, ad esempio con vim:

:w
E45: 'readonly' option is set (add ! to override)

D'altra parte, se si dice vidi scrivere il file nonostante le sue autorizzazioni, con l'utilizzo di qualcosa di simile :x!o :wq!, l'editor modifica temporaneamente le autorizzazioni per consentire la scrittura del file:

...
stat("test-file", {st_mode=S_IFREG|0444, st_size=7, ...}) = 0
getuid()                                = 1000
chmod("test-file", 0100644)             = 0
...
open("test-file", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4
write(4, "I am good singer,\n", 18)               = 18
fsync(4)                                = 0
close(4)                                = 0
chmod("test-file", 0100444)             = 0
....

In tal caso, il numero di inode rimane invariato.

Infine, questo non è un bug come se non ti fosse permesso di cambiare i permessi del file, non puoi modificarlo vi.


Hah! Dopo aver pubblicato la mia risposta, ho fatto alcuni esperimenti e ho finito per spendere quasi un'ora eseguendo Vim attraverso lo strace per vedere cosa stava facendo dietro le quinte in diverse situazioni (diverse permutazioni di permessi e proprietà del file e della directory principale). Ho appena visto la tua risposta dopo aver finito di riassumere i risultati dei miei esperimenti. È stata una bella esperienza di apprendimento.
Anthony Geoghegan,
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.