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, y salvé y renuncié :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
Por lo tanto, el usuario root debería tener acceso a R / W y todos los demás solo deberían haber leído. Edite el archivo, intente guardar, no puede. Impresionante, trabajando según lo previsto. Sin embargo, si guarda con :w!
, vim cambia de algún modo 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
¡ Todavía puedes sobrescribir con :w!
! ¿Qué está pasando? ¿Cómo puede violar las leyes de propiedad de archivos y permisos como este? Miré la página de ayuda en vim diciendo :help :w
y 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 corazón de mi pregunta es, ¿cómo puedo hacer que un archivo no sea editable por vim y por qué no se basa en el archivo? permisos del sistema, como era de esperar, y ¿qué mecanismo está usando vim para editar el archivo que otros editores (gedit, nano) no pueden usar?
EDITAR: La computadora en la que probé esto está usando 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.
fuente
CAP_CHOWN
Se requiere llamarchown(2)
. Por cierto, puedo reproducir en Debian, con vim 7.4.Respuestas:
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 antiguo y renombrar el nuevo con diferentes permisos?
¡Esto es exactamente lo que hace vim!
Si ejecuta vim bajo strace, por ejemplo:
Basado en este registro, puedo adivinar el siguiente proceso:
Algunas verificaciones de permisos anteriores (e
chown
intentos, etc.) se omiten por brevedad.open
Intento de abrir el archivo para escritura (falla: permiso denegado)lstat
Comprueba el propietario del archivogetuuid
Verifique la ID de usuario actual para ver si coinciden con el propietario del archivounlink
Elimine el archivo (esto está permitido porque tiene permiso de escritura en el directorio)open
Crea un nuevo archivo con el mismo nombrewrite
El contenido del archivo (leído anteriormente, escribí algunas galimatías)fsync
Vaciar el archivo al disco (no es realmente importante)close
chmod
Cambie los permisos del nuevo archivo para que se parezca al anterior; ahora tiene un nuevo propietario.fuente
:w!
, lo cual tiene sentido.strace
: usar la-o
opción para escribir la salida en un archivo; de lo contrario, choca convim
la salida de. En cuanto a los permisos de escritura, no veo que la comprobación de permisos de directorio constat
pero no intente crear un archivo (llamado así4913
, parece aleatorio) en el directorio actual y luego eliminarlo.4913
realidad es solo el primer nombre que intenta, y su propósito es verificar si tiene suficientes permisos para hacerlo. Ver: bugzilla.redhat.com/show_bug.cgi?id=427711#c6 y groups.google.com/forum/#!topic/vim_dev/sppdpElxY44