Saya menggunakan Vim tempo hari seperti biasa, ketika saya melihat sesuatu yang aneh. Inilah yang saya lakukan:
~$ touch testfile
~$ ls -l | grep testfile
-rw-r--r-- 1 username groupname 0 Jul 23 10:00 testfile
~$ vim testfile
Lalu saya membuat perubahan, dan menabung dan berhenti bersama :wq
. Cukup normal. Namun, kemudian:
~$ 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
Jadi root harus memiliki akses r / w dan semua orang seharusnya hanya membaca. Edit file, coba simpan - Anda tidak bisa. Luar biasa, bekerja sebagaimana mestinya. Namun, jika Anda menyimpan dengan :w!
, vim entah bagaimana mengubah kepemilikan file kembali ke nama pengguna: usergroup dan file tersebut disimpan. Bahkan jika Anda melakukan ini:
~$ sudo chmod 444 testfile
~$ sudo -k
~$ ls -l | grep testfile
-r--r--r-- 1 root root 0 Jul 23 10:06 testfile
~$ vim testfile
Anda masih bisa menimpa :w!
! Apa yang terjadi? Bagaimana vim dapat melanggar hukum kepemilikan file dan izin seperti ini? Saya melihat halaman bantuan di vim dengan mengatakan :help :w
dan menemukan ini:
: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.
Saya tidak dapat menulis ke file dalam vim sebelumnya ketika saya tidak seharusnya, jadi saya kira inti sebenarnya dari pertanyaan saya adalah, bagaimana saya bisa membuat file tidak dapat diedit oleh vim dan mengapa tidak didasarkan pada file izin sistem, seperti yang saya harapkan, dan mekanisme apa yang digunakan vim untuk mengedit file yang tidak dapat digunakan oleh editor lain (gedit, nano)?
EDIT: Komputer tempat saya mencoba ini menggunakan kernel Linux 3.15.5-2-ARCH. Nomor versi Vim adalah 7.4.373-1, dan yang diinstal oleh pacman
- Saya tidak mengkompilasinya dari awal dengan opsi khusus.
sumber
CAP_CHOWN
diperlukan untuk meneleponchown(2)
. Ngomong-ngomong, saya bisa mereproduksi di Debian, dengan vim 7.4.Jawaban:
Saya dapat melihat bahwa jalur Anda saat ini adalah
~
, direktori home pengguna Anda. Anda harus memiliki izin menulis ke direktori itu.Pikirkan dengan cara lain - jika Anda telah membaca dan menulis izin ke direktori, apa yang menghentikan Anda dari menyalin file, menghapus yang lama dan mengganti nama yang baru dengan izin yang berbeda?
Inilah yang dilakukan vim!
Jika Anda menjalankan vim di bawah strace, misalnya:
Berdasarkan log ini, saya bisa menebak proses berikut:
Beberapa pemeriksaan izin sebelumnya (dan
chown
upaya, dll.) Dihilangkan karena singkatnya.open
Mencoba membuka file untuk ditulis (gagal: izin ditolak)lstat
Periksa pemilik filegetuuid
Periksa ID pengguna saat ini, untuk melihat apakah mereka cocok dengan pemilik fileunlink
Hapus file (ini diizinkan karena izin tulis pada direktori)open
Buat file baru dengan nama yang samawrite
Isi file (baca sebelumnya, saya mengetikkan omong kosong)fsync
Siram file ke disk (tidak terlalu penting)close
chmod
Ubah izin file baru agar terlihat seperti yang lama - kebetulan memiliki pemilik baru sekarang.sumber
:w!
, yang masuk akal.strace
: gunakan-o
opsi untuk menulis keluaran ke file; selain itu bentrok denganvim
output. Adapun menulis izin, saya tidak melihatnya memeriksa izin direktori denganstat
tetapi tidak mencoba untuk membuat file (bernama4913
, tampaknya acak) di direktori saat ini dan kemudian menghapusnya.4913
sebenarnya hanya nama pertama yang dicoba, dan tujuannya adalah untuk memeriksa apakah ia memiliki cukup izin untuk melakukannya. Lihat: bugzilla.redhat.com/show_bug.cgi?id=427711#c6 dan groups.google.com/forum/#!topic/vim_dev/sppdpElxY44