
Estoy tratando de entender por qué sudo no tiene permiso aquí
touch fred.txt
/tmp$ ls -la fred.txt
-rw-rw-r-- 1 me me 0 Dec 12 15:40 fred.txt
/tmp$ sudo -i
~# cd /tmp
/tmp# echo hi >> fred.txt
-bash: fred.txt: Permission denied
/tmp# chmod 666 fred.txt
/tmp# ls -la fred.txt
-rw-rw-rw- 1 me me 0 Dec 12 15:40 fred.txt
/tmp# echo hi >> fred.txt
-bash: fred.txt: Permission denied
id
uid=0(root) gid=0(root) groups=0(root)
Según tengo entendido, el permiso 666 debería otorgar al propietario, al grupo y a otros permisos para leer y escribir el archivo. Surly sudo, que actúa como root, como lo demuestra el comando id, tiene acceso al archivo con el permiso "otro".
¿Qué estoy entendiendo mal aquí?
Respuesta1
Tiene algo que ver coneste compromisoen el kernel de Linux. A menudo /tmp
es "escribible en todo el mundo" ("mundo" aquí significa "otros") y es "pegajoso":
$ stat /tmp/
...
Access: (1777/drwxrwxrwt) Uid: ( 0/ root) Gid: ( 0/ root)
...
chmod(2)
:
...
S_ISVTX (01000) sticky bit (restricted deletion flag, as described in unlink(2))
...
S_IWOTH (00002) write by others
...
Como se menciona en el mensaje de confirmación, no le impide exactamente escribir en un archivo afectado, pero sí abrir dicho archivo con O_CREAT
, que es una marca paraopen()
que normalmente está configurado para activar la creación de archivos si el destino aún no existe. Por lo tanto, aún puedes escribir en un archivo afectado con el indicador sin configurar (lo cual se puede hacer con dd
):
# ls -l /tmp/meh
-rwxrwxrwx 1 tom tom 0 Dec 12 17:33 /tmp/meh
# id
uid=0(root) gid=0(root) groups=0(root)
# echo test | dd of=/tmp/meh oflag=append conv=notrunc
dd: failed to open '/tmp/meh': Permission denied
# echo test | dd of=/tmp/meh oflag=append conv=notrunc,nocreat
0+1 records in
0+1 records out
5 bytes copied, 9.4981e-05 s, 52.6 kB/s
#
Tenga en cuenta que se trata únicamente de si el indicador está configurado, pero no de si es necesario crear un archivo, ya que, en caso de preocupación, el archivo siempre existe.
También tenga en cuenta que, como se menciona en el mensaje de confirmación, el archivo no se pudo abrir O_CREAT
sinjustoporque no era propiedad del usuario que intentó abrirlo ( root
), sino también porque su dueño ( tom
) es diferente al dueño ( root
) del directorio ( /tmp
). Si /tmp/
fuera propiedad de tom
tal como /tmp/meh
era, root
habría sidocapazpara abrirlo con O_CREAT
.
Ver tambiéneste compromisoen systemd que habilita la "protección" en las distribuciones que lo adoptaron:
# sysctl fs.protected_regular
fs.protected_regular = 1
Tenga en cuenta que los sistemas relacionadosTambién se puede configurar 2
(o 0
).