Preguntas frecuentes

¿Puedo usar subprocesos?

Sí, los subprocesos son compatibles con Sandbox2.

Todos los subprocesos deben estar en zona de pruebas

Debido al funcionamiento de Linux, la política seccomp-bpf se aplica solo al subproceso actual. Esto significa que la política no se aplica a otros subprocesos existentes, pero los futuros subprocesos heredarán la política:

  • Si usas Sandbox2 en el primer modo en el que la zona de pruebas está habilitada antes del execve(), todos los subprocesos heredarán la política, y no habrá problema. Este es el modo preferido de zona de pruebas.
  • Si usas el segundo modo, en el que el ejecutor tiene set_enable_sandbox_before_exec(false) y el Sandboxee le indica al ejecutor cuándo desea establecer una zona de pruebas con SandboxMeHere(), asegúrate de que el filtro se aplique a todos los subprocesos. De lo contrario, existe el riesgo de que se produzca un escape en la zona de pruebas: el código malicioso podría migrar de un subproceso de zona de pruebas a un subproceso no incluido en la zona de pruebas.

¿Cómo debo compilar mi Sandboxee?

Si no tienes cuidado, es fácil heredar muchas dependencias y efectos secundarios (llamadas de sistema adicionales, accesos a archivos o incluso conexiones de red) que dificultan la creación de zonas de pruebas (realizan un seguimiento de todos los efectos secundarios) y menos seguras (porque las políticas de archivos y llamadas del sistema son más amplias). Algunas opciones de compilación pueden ayudar a reducir esos problemas:

  • Compila de forma estática el objeto binario de Sandboxee para evitar la vinculación dinámica, que usa muchas llamadas del sistema (open/openat, mmap, etcétera).
  • Dado que Bazel agrega pie de forma predeterminada, pero estático no es compatible con él, considera usar la marca de funciones para forzar su desactivación mediante las siguientes opciones en las reglas cc_binary:

    linkstatic = 1,
    features = [
        "fully_static_link",  # link libc statically
        "-pie",
    ],
    

Sin embargo, usar la estática tiene la desventaja de reducir la entropía del montón ASLR (de 30 a 8 bits), lo que facilita las vulnerabilidades. Decide cuidadosamente qué es preferible según tu implementación y política de la zona de pruebas:

  • No estático: Buen ASLR del montón, que puede ser más difícil de obtener la ejecución inicial del código, pero a costa de una política de zona de pruebas menos eficaz, potencialmente más fácil de abandonar.
  • static: ASLR del montón erróneo, potencialmente más fácil de obtener la ejecución del código inicial, pero una política de zona de pruebas más eficaz, potencialmente más difícil de salir.

Esta opción es lamentable, ya que el compilador no admite PIE estático (Position Independent ejecutables). Para implementar PIE, el objeto binario es un objeto dinámico, y el cargador dinámico lo asigna a una ubicación aleatoria antes de ejecutarlo. Entonces, debido a que el montón tradicionalmente se coloca en un desplazamiento aleatorio después de la dirección base del objeto binario (y se expande con la llamada de sistema brk), esto significa que para los objetos binarios estáticos, la entropía ASLR del montón es solo este desplazamiento porque no hay PIE.

Para ver ejemplos de estas opciones de compilación, observa el ejemplo estático BUILD.bazel: static_bin.cc se compila de forma estática, lo que nos permite tener una política de llamada de sistema muy estricta. Esto también funciona bien para la zona de pruebas de objetos binarios de terceros.

¿Puedo hacer una zona de pruebas de objetos binarios x86 de 32 bits?

Sandbox2 solo puede crear una zona de pruebas con la misma arquitectura con la que se compiló.

Además, se quitó la compatibilidad con x86 de 32 bits de Sandbox2. Si intentas usar un ejecutor x86 de 64 bits para hacer una zona de pruebas de un objeto binario x86 de 32 bits o un binario x86 de 64 bits que realiza llamadas de sistema de 32 bits (a través de int 0x80), ambos generarán una infracción de la zona de pruebas que se puede identificar con la etiqueta de arquitectura [X86-32].

La razón detrás de este comportamiento es que los números de llamada de sistema difieren entre las arquitecturas y, debido a que la política de llamada de sistema está escrita en la arquitectura del ejecutor, sería peligroso permitir una arquitectura diferente para Sandboxee. De hecho, esto podría permitir una llamada de sistema aparentemente inofensiva que, de hecho, significa que otra llamada del sistema más dañina podría abrir la zona de pruebas para escapar.

¿Hay algún límite en la cantidad de zonas de pruebas que puede solicitar un proceso del ejecutor?

Para cada instancia de Sandboxee (nuevo proceso generado desde el servidor de bifurcación), se crea un subproceso nuevo. Ahí es donde se encuentra la limitación.

¿Un ejecutor puede solicitar la creación de más de una zona de pruebas?

No. Hay una relación de 1:1: una instancia del Ejecutor almacena el PID de Sandboxee, administra la instancia de Comms con la de Sandbox, etcétera.

¿Por qué obtengo el mensaje “Función no implementada” dentro de forkserver.cc?

Sandbox2 solo admite la ejecución en kernels razonablemente nuevos. Nuestro corte actual es el kernel 3.19, aunque eso podría cambiar en el futuro. Esto se debe a que estamos usando funciones de kernel relativamente nuevas, como los espacios de nombres de usuarios y seccomp con la marca TSYNC.

Si ejecutas en producción, esto no debería ser el problema, ya que casi toda la flota ejecuta un kernel lo suficientemente nuevo. Si tienes algún problema, comunícate con nosotros.

Si ejecutas en Debian o Ubuntu, actualizar tu kernel es tan fácil como ejecutarlo:

sudo apt-get install linux-image-<RECENT_VERSION>