¿Vim puede romper los permisos de los archivos?

¿Vim puede romper los permisos de los archivos?

Estaba usando Vim el otro día como siempre, cuando noté algo extraño. Esto es lo que hice:

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

Luego hice un cambio, guardé y salí con :wq. Muy normal. Entonces, sin embargo:

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

Entonces root debería tener acceso r/w y todos los demás solo deberían haber leído. Edite el archivo, intente guardarlo, no puede. Impresionante, funcionando según lo previsto. Sin embargo, si guarda con :w!, vim de alguna manera cambia la propiedad del archivo a nombre de usuario: grupo de usuarios y el archivo se guarda. Incluso si haces esto:

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

Puedeaúnsobrescribir con :w!! ¿Lo que está sucediendo? ¿Cómo puede vim violar las leyes de propiedad y permiso de archivos de esta manera? Miré la página de ayuda en vim diciendo :help :wy encontré esto:

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

No he podido escribir en un archivo en vim anteriormente cuando no debería, así que supongo que el verdadero centro de mi pregunta es, ¿cómo puedo hacer que vim no pueda editar un archivo y por qué no está basado en el archivo? permisos del sistema, como era de esperar, y ¿qué mecanismo usa vim para editar el archivo que otros editores (gedit, nano) no pueden usar?

EDITAR: La computadora en la que probé esto usa el kernel de Linux 3.15.5-2-ARCH. El número de versión de Vim es 7.4.373-1, y es el que instaló pacman; no lo compilé desde cero con ninguna opción especial.

Respuesta1

Puedo ver que su ruta actual es ~el directorio de inicio de su usuario. Debería tener permisos de escritura en ese directorio.

Piénselo de otra manera: si tiene permisos de lectura y escritura en el directorio, ¿qué le impide copiar el archivo, eliminar el anterior y cambiar el nombre del nuevo con permisos diferentes?

¡Esto es exactamente lo que hace vim!


Si ejecuta vim bajo strace, por ejemplo:

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

Según este registro, puedo adivinar el siguiente proceso:

Algunas comprobaciones de permisos anteriores (e chownintentos, etc.) se omiten por brevedad.

  1. openIntenta abrir el archivo para escribir (falla: permiso denegado)
  2. lstatVerifique el propietario del archivo
  3. getuuidVerifique la ID de usuario actual para ver si coincide con el propietario del archivo.
  4. unlinkElimine el archivo (esto está permitido porque tiene permiso de escritura en el directorio)
  5. openCrea un nuevo archivo con el mismo nombre
  6. writeEl contenido del archivo (leído antes, escribí algunas tonterías)
  7. fsyncVacíe el archivo en el disco (no es realmente importante)
  8. close
  9. chmodCambie los permisos del nuevo archivo para que se parezca al anterior; resulta que ahora tiene un nuevo propietario.

información relacionada