Vim dapat merusak izin file?

8

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

sangat
sumber
Saya sepertinya tidak dapat mereproduksi masalah, kecuali mengambil beberapa trik seperti yang dijelaskan di sini
Davyzhu
Saya hanya mencobanya lagi menggunakan perintah dalam pertanyaan, dan itu terjadi dengan cara yang sama. Saya akan mengedit pertanyaan untuk menambahkan rincian tentang komputer saya karena sepertinya ini mungkin tergantung platform.
zrneely
Firasat pertama saya adalah Anda diizinkan mengubah kepemilikan file di direktori yang memiliki akses tulis untuk Anda. Tapi sepertinya bukan itu masalahnya . CAP_CHOWNdiperlukan untuk menelepon chown(2). Ngomong-ngomong, saya bisa mereproduksi di Debian, dengan vim 7.4.
Bob

Jawaban:

10

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:

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

Berdasarkan log ini, saya bisa menebak proses berikut:

Beberapa pemeriksaan izin sebelumnya (dan chownupaya, dll.) Dihilangkan karena singkatnya.

  1. open Mencoba membuka file untuk ditulis (gagal: izin ditolak)
  2. lstat Periksa pemilik file
  3. getuuid Periksa ID pengguna saat ini, untuk melihat apakah mereka cocok dengan pemilik file
  4. unlink Hapus file (ini diizinkan karena izin tulis pada direktori)
  5. open Buat file baru dengan nama yang sama
  6. write Isi file (baca sebelumnya, saya mengetikkan omong kosong)
  7. fsync Siram file ke disk (tidak terlalu penting)
  8. close
  9. chmod Ubah izin file baru agar terlihat seperti yang lama - kebetulan memiliki pemilik baru sekarang.
Bob
sumber
Ok terima kasih. Aku senang aku tahu ini. Jadi jika saya tidak memiliki izin menulis di direktori, saya tidak akan dapat menggunakan :w!, yang masuk akal.
zrneely
Juga, informasi strace sangat berguna - sekarang saya memiliki alat lain untuk penyelidikan saya sendiri di masa depan.
zrneely
1
@ zrneely Tip untuk strace: gunakan -oopsi untuk menulis keluaran ke file; selain itu bentrok dengan vimoutput. Adapun menulis izin, saya tidak melihatnya memeriksa izin direktori dengan stattetapi tidak mencoba untuk membuat file (bernama 4913, tampaknya acak) di direktori saat ini dan kemudian menghapusnya.
Bob
Sepertinya 4913sebenarnya 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
Bob