¿Por qué se requiere privs para setgid () a grupos suplementarios?

8

Las diversas set*gid()llamadas al sistema requieren privilegios para cambiar de grupo, excepto en muy pocos casos. Cambiar el grupo primario a uno de los grupos suplementarios de los procesos no parece ser uno de ellos, lo que significa que los comandos newgrp/ sgpor ejemplo necesitan elevar los privilegios para cambiar el grupo primario.

¿Hay alguna razón por la cual setgid()/ setegid()/ setregid()/ setfsgid()no permita cambiar a un grupo suplementario sin privs? Si es así, ¿cuál es la razón?

William Hay
fuente
1
No estoy seguro tampoco. Tenga en cuenta que puede cambiar un archivo a uno de sus grupos suplementarios, por lo que si tiene acceso de escritura a un área sin noexec, nosuid, puede solucionar esa limitación (creando una copia /usr/bin/envcon permiso setgid).
Stéphane Chazelas
El comando newgrp ya lo hace AFAICT por mí, pero generar un programa externo no siempre es lo que uno quiere hacer.
William Hay
Tenga en cuenta que se newgrp/sgrefiere a la base de datos de la cuenta, no a la lista de grupos complementarios del proceso.
Stéphane Chazelas
Si su gid no está también en su lista de identificadores suplementarios, permitirlo setgid()le permitiría abandonar la membresía de un grupo (lo que sería un problema de seguridad), pero nuevamente podría hacerlo con el mismo truco ejecutable setgid que el anterior, y su gid generalmente también está en su lista complementaria ( initgroups(3)toma un argumento gid solo para eso).
Stéphane Chazelas

Respuestas:

3

Por supuesto, el enigma fundamental aquí es que las verificaciones de permisos del sistema de archivos se basan en la combinación de (el UID efectivo y) el GID efectivo y los GID suplementarios. Entonces, desde el punto de vista de las verificaciones de permisos de archivos, el GID efectivo es equivalente a los GID suplementarios, lo que lleva a la pregunta del OP. (De paso: si estamos hablando de Linux, en realidad es el UID / GID del sistema de archivos que se usa en las verificaciones de permisos del sistema de archivos, en lugar del UID y GID efectivos, pero las ID anteriores casi siempre tienen los mismos valores que las últimas ID. )

Por lo tanto, debe haber algunos casos en los que los GID reales / efectivos / guardados no sean equivalentes a los GID suplementarios. (Agrupo los GID de conjunto real / efectivo / guardado, porque las reglas de permiso set * gid () normales dicen que un proceso no privilegiado puede cambiar cualquiera de esos GID al mismo valor que uno de los otros dos).

Y de hecho, hay algunos de esos casos. access (2) realiza sus comprobaciones en función de la ID de usuario real y la ID de grupo del proceso. Si un usuario no privilegiado pudo cambiar la ID de grupo real para que sea la misma que una de las GID adicionales que no es la GID establecida efectiva o guardada, entonces el comportamiento de acceso (2) podría ser manipulado.

Hay otros casos de este tipo. Consulte la página del comando man mkdir (2) de Linux , por ejemplo. Dependiendo de si el bit de modo set-GID está configurado en el directorio padre, un nuevo archivo creado en el directorio toma la propiedad de su grupo del GID efectivo del proceso de creación. Nuevamente, si un proceso no privilegiado podría cambiar su GID efectivo para que sea el mismo que uno de sus GID suplementarios, podría manipular la propiedad del grupo de nuevos archivos de maneras inesperadas. Se aplican comentarios similares para mknod (2) y las llamadas IPC de System V semget (2), shmget (2) y msgget (2).

También hay algunos casos específicos de Linux donde los GID del conjunto real / efectivo / guardado no son equivalentes a los GID suplementarios. Ver process_vm_readv (2) y prlimit (2), por ejemplo.

mtk
fuente
Nota: @mtk es el autor de la interfaz de programación de Linux .
Stéphane Chazelas
El gid efectivo determina la propiedad del grupo de nuevos archivos. Pero luego puede cambiar ese grupo a uno de sus gids suplementarios después (y también dar el bit setgid permitiendo que su proceso realice efectivamente un setgid ()). Entonces parece un poco una razón débil.
Stéphane Chazelas
@ StéphaneChazelas: de acuerdo, es un poco débil. En OTOH, ese es ahora un proceso de dos pasos, que (y estoy llegando aquí) tiene el potencial para razas raras. Pero, aparte de ese caso, están los otros que menciono anteriormente. No sé qué razón precisa hubo para esta decisión de diseño. Quizás fue acceso (2), ya que es una parte antigua de la API. Muchos de los otros solo llegaron más tarde (o son específicos de Linux) o (supongo) que no estaban presentes en BSD cuando se agregaron GID adicionales. O, tal vez, se trataba solo de preservar el comportamiento histórico; Veo que agregaste ese punto como respuesta.
mtk
3

Creo que la razón es principalmente histórica. Los grupos suplementarios no se agregaron hasta 4.2BSD (alrededor de 1983). Antes de eso, solo tenía los fluidos y fluidos reales y efectivos.

El comportamiento de setuid / setgid era completamente simétrico y no tenía razón para no serlo. Cambiaría de usuario suy grupo con sg/ newgrptodos los ejecutables setuid. La información sobre la pertenencia al grupo de usuarios residía solo en la base de datos de usuarios, no en los atributos de los procesos.

Y la interfaz setuid / setgid no cambió cuando se agregaron gids suplementarios.

Técnicamente ahora, si tiene acceso de escritura a un sistema de archivos (donde la ejecución y setuid / setgid no están deshabilitados), aún puede configurar su ID de usuario real o real en cualquiera de sus gids adicionales (sin tener que recurrir a sg/ newgrpque por cierto solo permitir cambiar a grupos definidos en la base de datos de usuarios, que no es necesariamente la misma que la lista de gids suplementarios del proceso).

cp /usr/bin/env .
chgrp any-sup-group env
chmod g+s ./env

Y al ejecutar env, su egid cambia a any-sup-group.

Stéphane Chazelas
fuente