2012-04-03 10 views
5

Actualmente estoy trabajando en el back-end del sistema de concurso de programación pública similar a ACM. En dicho sistema, cualquier usuario puede enviar una fuente de código, que se compilará y ejecutará automáticamente (lo que significa que no se realiza una premoderación de ojo humano) para intentar resolver algún problema de cómputo.Cómo prohibir las llamadas al sistema, GNU/Linux

Back-end es una máquina dedicada a GNU/Linux, donde se creará un usuario para cada concursante, todos los usuarios que forman parte del grupo de usuarios. Las fuentes enviadas por cualquier usuario en particular serán almacenadas en el directorio de inicio del usuario, luego compiladas y ejecutadas para ser verificadas en varios casos de prueba.

Lo que quiero es prohibir el uso de llamadas al sistema Linux para las fuentes. Esto se debe a que los problemas requieren soluciones independientes de la plataforma, mientras que habilitar las llamadas al sistema para fuentes inseguras es una posible violación de la seguridad. Tales fuentes pueden colocarse con éxito en el SF, incluso compilarse, pero nunca ejecutarse. También quiero recibir notificaciones cada vez que se envíe una fuente que contenga llamadas al sistema.

Por ahora, ver los siguientes lugares donde tales corrector puede Posición: análisis

  • -Frontales/pre-compilación - fuente ya comprobado en el sistema, pero que aún no compilado. Comprobador de texto simple contra nombres de llamadas al sistema. Solución dependiente de la plataforma, independiente del compilador y dependiente de la plataforma.
  • Parche del compilador - bloqueo GCC (o cualquier otro compilador incluido en la cadena de herramientas) cada vez que se produce una llamada al sistema. Solución dependiente de la plataforma, dependiente del compilador, independiente del idioma (si colocamos el verificador "lo suficientemente lejos"). La compatibilidad también puede perderse. De hecho, no me gusta más esta alternativa.
  • Comprobador de tiempo de ejecución - siempre que se invoca una llamada al sistema desde el proceso, finalice este proceso e informe. Esta solución es independiente del lenguaje y del compilador, pero depende de la plataforma: estoy de acuerdo con eso, ya que implementaré el back-end en plataformas similares a corto y mediano plazo.

Entonces, la pregunta es: ¿proporciona GNU/Linux una oportunidad para que el administrador prohíba el uso de llamadas del sistema para un grupo de usuarios, un usuario o un proceso particular? Puede ser una política de seguridad o una utilidad GNU ligera.

Intenté Google, pero Google no me gustó hoy.

+0

_Front-end/pre-compilation analysis_ ← los trucos del preprocesador pueden evadir esto fácilmente. Hay 'seccomp' que es un modo en el que un proceso solo puede leer/escribir en una tubería abierta previamente. Está habilitado a través de una llamada 'prctl()'. Hay preguntas similares aquí en SO: http://www.google.com/search?q=seccomp+site%3Astackoverflow.com&btnG=Buscar&oe=utf-8 – ninjalj

+0

@ninjalj lo intentó, pero no lo encontró. ¿Te importa compartir un enlace? – iehrlich

+0

Acabo de agregar un enlace a mi comentario anterior. – ninjalj

Respuesta

7

modo 1 seccomp permite que un proceso se limita a exactamente cuatro llamadas al sistema: read, write, sigreturn y _exit. Esto se puede utilizar para codificar severamente sandbox, como lo hace seccomp-nurse.

mode 2 seccomp (en el momento de la redacción, se encuentra en Ubuntu 12.04 o patch your own kernel) proporciona más flexibilidad en el filtrado de syscalls.Puede, por ejemplo, configurar primero los filtros, luego exec el programa bajo prueba. El uso adecuado de chroot o unshare se puede utilizar para evitar que vuelva a exec cualquier otra cosa "interesante".

+1

@suddnely_me Solo pensé en otra alternativa, si seccomp no funciona: un entorno limitado basado en [NaCL] (https://developers.google.com/native-client/) como [ZeroVM] (http://zerovm.org/). – ephemient

3

Creo que necesita definir mejor la llamada al sistema. Quiero decir,

cat <<EOF > hello.c 
#include <stdio.h> 
int main(int argc,char** argv) { 
    fprintf(stdout,"Hello world!\n"); 
    return 0; 
} 
EOF 
gcc hello.c 
strace -q ./a.out 

demuestra que incluso un programa aparentemente trivial realiza ~ 27 llamadas al sistema. Usted (supongo) desea permitir llamadas a la "biblioteca C estándar", pero esas a su vez se implementarán en términos de llamadas al sistema. Creo que lo que trato de decir es que la verificación en tiempo de ejecución es menos factible de lo que se podría pensar (usando strace o similar de todos modos).

Cuestiones relacionadas