2009-06-26 13 views
11

Tuve que hacer un hack de Linux sucio para que alguien pudiera iniciar una impresora con el comando de shell cupsenable printername mientras era un usuario no root. No quería que pudieran utilizar la totalidad de la sintaxis cupsenable como raíz, así que acabo de escribir un contenedor C que desinfecta la entrada en argv[1] y llama al system("cupsenable sanitizedprintername").¿Por qué necesito setuid (0) dentro de un programa setuid-root C que llama a un programa administrativo con system()?

Hice la raíz del programa setuid, pero aún así, cupsenable falló con "permiso denegado". Luego inserté una llamada setuid(0) antes de system() y, he aquí, funcionó.

Ignore el problema de que haya una mejor manera de otorgar a los usuarios el control de la impresora. Probablemente haya una mejor manera. Lo que me interesa son las complejidades de chmod u+s vs. setuid(0) contra system(). ¿Por qué se comportó de esa manera?

Respuesta

17

De man system:

No utilice system() de un programa con set-user-ID o set-group-ID privilegios, porque los valores extraños para algunas variables de entorno pueden ser utilizados para subvertir la integridad del sistema. Use la familia de funciones exec(3) en su lugar, pero no execlp(3) o execvp(3). system(), de hecho, no funcionará correctamente desde programas con privilegios de ID de usuario fijo o ID de grupo establecido en sistemas en los que /bin/sh es la versión 2 de bash, ya que bash 2 descarta privilegios al inicio.

Y a partir de man bash:

Si la envoltura se inicia con el usuario (grupo) efectivo ID no es igual al usuario real (grupo) Identificación, y la opción -p no se suministra, no está en puesta los archivos se leen, las funciones de shell no se heredan del entorno, la variable SHELLOPTS, si aparece en el entorno, se ignora y la identificación de usuario efectiva se establece en la identificación de usuario real.

Parece su llamada setuid(0) eludido esa protección.

+2

Whoa. Bueno, dije que estaba sucio. Parece que lo que hice fue convencer al proceso bash engendrado por el sistema() de que realmente, realmente, honestamente era root, juro por Dios. Parece que algunas refactorizaciones están en orden. – JCCyC

Cuestiones relacionadas