Vi dapat menulis ke file meskipun file hanya-baca

12

Contoh berikut menunjukkan cara membuat file dengan hanya izin baca. Seperti yang dapat kita lihat, ketika saya mencoba menulis ke file ini menggunakan perintah echo saya dapatkan Permission denied,.

Tetapi mengapa, jika kita menggunakan vi, apakah kita tidak mendapatkannya Permission denied? Seperti dapat dilihat di sini, kita dapat menulis ke file tersebut meskipun file tersebut hanya untuk dibaca.

Apa yang terjadi disini? Apakah ini 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
maihabunash
sumber
1
FYI ada situs beta SE untuk ini - vi.stackexchange.com
Raystafarian

Jawaban:

28

Catatan : Karena alasan lisensi legacy, sebagian besar distribusi GNU / Linux tidak menyertakan program vi asli seperti yang ditulis oleh Bill Joy. Sebaliknya, perintah vi disediakan dengan menjalankan Vim dalam mode kompatibilitas-vi. Jawaban berikut didasarkan pada menjalankan Vim dengan mode kompatibilitas-vi.

Memodifikasi file hanya baca

Vim memperingatkan pengguna jika mereka memodifikasi buffer file read-only W10: Warning: Changing a readonly file,. Jika pengguna mencoba menulis ke file ini, mereka mendapatkan pesan kesalahan berikut,'readonly' option is set (add ! to override) ,.

Ketika direktori induk dapat ditulisi oleh pengguna Vim

Vim, karena membantu, membuat pengguna tahu bahwa mereka dapat memaksa untuk menulis dengan menambahkan tanda seru, !pada wperintah. Jika versi paksa dari perintah tulis ini digunakan, Vim menghapus file asli (jika menggunakan Vim dengan backupset pilihan Vim saja , file asli sebenarnya diubah namanya menjadi sama dengan file cadangan). Ini kemudian membuka (membuat) file baru dengan nama yang sama seperti aslinya dan menulis konten buffer ke file baru ini. Ini dapat diamati dengan memeriksa inode file sebelum dan sesudah menjalankan 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

Catatan: Ini juga dapat mengubah izin dan kepemilikan file dan memecah tautan (simbolik), misalnya, jika file asli dimiliki oleh pengguna lain, file baru akan dimiliki oleh pengguna yang menjalankan Vim.

Suatu proses hanya dapat melakukan ini jika memiliki izin tertulis untuk direktori induk file. Secara umum, untuk memastikan bahwa suatu program tidak dapat memodifikasi file, izin dari file itu sendiri dan direktori induknya harus diamankan.

Ketika direktori induk tidak dapat ditulisi oleh pengguna Vim

Namun, bahkan dalam kasus ini, Vim masih melakukan yang terbaik untuk membantu pengguna yang ngotot untuk menulis file secara berlebihan. Jika pengguna Vim memiliki kepemilikan file, Vim dapat mengatasi pembatasan direktori induk read-only dengan mengubah sementara izin file (menggunakan chmodpanggilan sistem), menulis buffer ke file, menutup file dan kemudian mengubah izin kembali. Berikut ekstrak dari sistem panggilan yang dibuat saat menjalankan vi melalui 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

Catatan: Ini tidak terjadi jika pengguna Vim mengedit file yang tidak mereka miliki karena Vim tidak akan dapat mengubah izin file.

Tambahan

Untuk benar-benar yakin bahwa suatu file tidak dapat dimodifikasi (pada sistem GNU / Linux), jalankan chattrperintah sebagai superuser:

sudo chattr +i filename

Dari man chattr:

File dengan atribut 'i' tidak dapat dimodifikasi: tidak dapat dihapus atau diganti namanya, tidak ada tautan yang dapat dibuat ke file ini dan tidak ada data yang dapat ditulis ke file. Hanya superuser atau proses yang memiliki kemampuan CAP_LINUX_IMMUTABLE yang dapat mengatur atau menghapus atribut ini.

Anthony Geoghegan
sumber
2
Asap suci, itu menyeluruh!
Camille Goudeseune
4
@CamilleGoudeseune Setelah saya memposting versi pertama dari jawaban saya, saya melakukan beberapa percobaan dan akhirnya menghabiskan sekitar satu jam menjalankan Vim melalui strace untuk melihat apa yang dilakukannya di balik layar dalam situasi yang berbeda (permutasi yang berbeda dari izin dan kepemilikan kedua file dan direktori induk). Saya terkadang terbawa suasana, tetapi begitu saya menerbitkan jawaban, saya ingin memastikan bahwa apa yang saya katakan itu benar.
Anthony Geoghegan
5

Kebanyakan jika tidak semua viimplementasi mencegah Anda untuk menulis file jika Anda menggunakan biasa menyimpan perintah seperti baik ZZ, :w, :wqatau :x, misalnya dengan vim:

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

Di sisi lain, jika Anda meminta viuntuk menulis file terlepas dari izinnya, dengan menggunakan sesuatu seperti :x!atau :wq!, editor untuk sementara mengendurkan izin untuk memungkinkan file untuk ditulis:

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

Dalam hal ini, nomor inode dibiarkan tidak berubah.

Akhirnya, ini bukan bug seolah-olah Anda tidak diizinkan untuk mengubah izin file, Anda tidak dapat memodifikasinya vi.

Jlliagre
sumber
Hah! Setelah saya memposting jawaban saya, saya melakukan beberapa percobaan dan akhirnya menghabiskan hampir satu jam menjalankan Vim melalui strace untuk melihat apa yang dilakukannya di balik layar dalam situasi yang berbeda (permutasi yang berbeda dari izin dan kepemilikan kedua file dan direktori induk). Saya baru saja melihat jawaban Anda setelah saya selesai merangkum hasil percobaan saya. Itu adalah pengalaman belajar yang baik.
Anthony Geoghegan