¿Hay algún archivo que siempre exista y un usuario 'normal' no puede instalarlo?

14

Necesito esto para una prueba unitaria. Hay una función que hace lstat en la ruta del archivo que se pasa como parámetro. Tengo que activar la ruta del código donde lstatfalla (porque la cobertura del código debe alcanzar el 90%)

La prueba puede ejecutarse solo con un solo usuario, por lo tanto, me preguntaba si hay un archivo en Ubuntu que siempre exista, pero los usuarios normales no tienen acceso de lectura a él ni a su carpeta. (Por lstatlo tanto , fallaría a menos que se ejecute como root).

Un archivo inexistente no es una solución, porque hay una ruta de código separada para eso, que ya estoy activando.

EDITAR: La falta de acceso de lectura al archivo solo no es suficiente. Con eso lstattodavía se puede ejecutar. Pude activarlo (en mi máquina local, donde tengo acceso de root), creando una carpeta en / root y un archivo en él. Y establecer el permiso 700 en la carpeta. Así que estoy buscando un archivo que esté en una carpeta a la que solo pueda acceder root.

Gatito agazapado
fuente
66
En mi humilde opinión/etc/shadow
Romeo Ninov
3
No puede asumir la existencia de ningún archivo, porque su programa puede ejecutarse en un espacio de nombres chroot o separado. Si se supone que / proc está montado y que init no es nada especial, entonces /proc/1/fd/0debería hacerlo.
mosvy
1
@mosvy Gracias que funciona en mi máquina local. Hmm, entonces lo probaré también en el grupo de control de calidad y puesta en escena.
Gatito
2
¿Por qué está vinculando su código de prueba a una versión particular del sistema operativo cuando simplemente podría crear un archivo desechable y eliminar su propio acceso de lectura?
Kilian Foth
44
Yo diría que no es realmente una prueba unitaria una vez que comienza dependiendo de un sistema de archivos real, en lugar de burlado.
Toby Speight

Respuestas:

21

En los sistemas Linux modernos, debería poder usar /proc/1/fdinfo/0(información para el descriptor de archivo 1 (stdout) del proceso de id 1 ( initen el espacio de nombres pid raíz que debería ejecutarse como root)).

Puede encontrar una lista con (como usuario normal):

sudo find /etc /dev /sys /proc -type f -print0 |
  perl -l -0ne 'print unless lstat'

(eliminar -type fsi no desea restringir a archivos normales).

/var/cache/ldconfig/aux-cachees otro candidato potencial si solo necesita considerar los sistemas Ubuntu. Debería funcionar en la mayoría de los sistemas GNU, ya que /var/cache/ldconfigse crea lectura + escritura + búsqueda en la raíz solo mediante el ldconfigcomando que viene con la libc GNU.

Stéphane Chazelas
fuente
1
¡Gracias! Si /proc/1/fdinfo/0funciona en Ubuntu 16.04 y 18.04, eso es más que suficiente.
Gatito agachado
1
El uso /proc/1/fdinfo/0no necesariamente funciona en un contenedor (por ejemplo, un contenedor Docker), y a menudo las pruebas unitarias se ejecutan en dichos contenedores en CI.
Philipp Wendler
@PhilippWendler, ya mencioné el espacio de nombres pid raíz . El OP no está preguntando acerca de los contenedores, sino sobre los archivos garantizados para estar allí en el diseño del sistema de archivos de un sistema Ubuntu. Como los contenedores podrían contener cualquier diseño de archivo y directorio, esa pregunta no podría responderse allí.
Stéphane Chazelas
12

Mirando la página del comando man lstat (2) puede inspirarse en casos que podrían hacer que falle con errores distintos a ENOENT (el archivo no existe).

La más obvia es:

EACCES Se deniega el permiso de búsqueda para uno de los directorios en el prefijo de ruta de la ruta .

Por lo tanto, necesita un directorio desde el que no puede buscar.

Sí, puede buscar uno que ya esté en su sistema (¿tal vez /var/lib/privatesi existe?) Pero también podría crear uno usted mismo, con el equivalente de:

$ mkdir myprivatedir
$ touch myprivatedir/myunreachablefile
$ chmod 0 myprivatedir
$ ls -l myprivatedir/myunreachablefile

La operación lstat (2) fallará con EACCES aquí. (Eliminar todos los permisos del directorio garantiza eso. Tal vez ni siquiera necesite tanto y chmod -xeliminar permisos de ejecución sería suficiente, ya que se necesitan permisos de ejecución en un directorio para acceder a los archivos que se encuentran debajo).

Hay otra forma creativa de hacer que lstat (2) falle, mirando su página de manual:

ENOTDIR Un componente del prefijo de ruta de ruta no es un directorio.

Por lo tanto, intentar acceder a un archivo como /etc/passwd/nonexistentdebería desencadenar este error, que de nuevo es diferente de ENOENT ("No existe tal archivo o directorio") y podría satisfacer sus necesidades.

Otro es:

El camino ENAMETOOLONG es demasiado largo.

Pero es posible que necesite un nombre realmente largo para este (creo que 4.096 bytes es el límite típico, pero su sistema / sistema de archivos podría tener uno más largo).

Finalmente, es difícil saber si alguno de estos será realmente útil para usted. Dices que quieres algo que no active el escenario "el archivo no existe". Aunque normalmente eso significa un error ENOENT, en la práctica muchas verificaciones de nivel superior simplemente interpretarán cualquier error de lstat (2) como "no existe". Por ejemplo, test -eo el equivalente [ -e ...]del shell podría simplemente interpretar todo lo anterior como "no existe", especialmente porque no tiene una buena manera de devolver un mensaje de error diferente y no devolver un error implicaría que el archivo existe, lo cual ciertamente no es el caso.

filbranden
fuente
@StephaneChazelas ¡Gran punto! Actualizado.
filbranden
6

Puedes findhacerlo tú mismo.

Uso /etc: el directorio de archivos de configuración como punto de partida:

sudo find /etc -type f -perm 0400 -user root

En mi sistema, esto no devuelve nada.

Puede ser un grupo menos restrictivo y permitir root(solo el usuario rootdebe ser miembro del grupo root), y busque un permiso de 440:

sudo find /etc -perm 0440 -user root -group root

En mi sistema esto devuelve:

/etc/sudoers.d/README
/etc/sudoers

Editar:

Según su edición, está buscando un directorio que no tenga permiso suficiente para que el usuario que lo invoca impida la inclusión del directorio:

sudo find / -perm o-rwx -type d -user root -group root 

Aquí estoy buscando directorios ( -type d) que carecen de los bits permanentes de lectura-escritura-ejecución para otros ( o-rwx) y que es propiedad de root:root.

Técnicamente, solo la ausencia de bit execute ( x) evitaría una lista de directorio ( lstat(2)) en el directorio.

En la salida que encontré /run/systemd/inaccessible/en mi sistema basado en init Systemd.

En cuanto a los archivos en /proc, /sys, /dev:

  • Estos sistemas de archivos son FS virtuales, es decir, residen en la memoria, no en el disco

  • Si planea confiar /proc, use, /proc/1/es decir, confíe en algo bajo PID 1, no cualquier PID posterior para tener confiabilidad / consistencia ya que no se garantiza que existan los PID (procesos) posteriores.

heemayl
fuente
Gracias, creo que mi pregunta está mal. Todavía puedo instalar archivos sin acceso de lectura a ellos. ¿Quizás el acceso a la carpeta tiene que ser limitado? (Modifiqué el título)
Crouching Kitten
Gracias. Con find / -type d -perm 0400 -user rootHe encontrado el directorio /proc/20/map_files/, si me refiero a un nombre de archivo inventado dentro de esa carpeta, como /proc/20/map_files/asdasd, entonces siempre falla. ¿Esa carpeta siempre existe en Ubuntu?
Gatito
@CrouchingKitten, los directorios /proc/1/pueden ser más seguros, ya que init siempre existe. Pero eso procno es un sistema de archivos normal, en caso de que importe.
ilkkachu
Gracias, di un voto positivo, pero acepté la otra respuesta, porque dijo que está garantizado que /proc/1/fdinfo/0funcione en Ubuntus moderno.
Gatito agachado
-perm o-rwxes como -perm 0, para empezar, todos los bits están apagados. Aquí te gustaría ! -perm -1.
Stéphane Chazelas