¿Puedo usar hilos?
Sí, los subprocesos son compatibles con Sandbox2.
Todos los subprocesos deben estar en un entorno de pruebas.
Debido a la forma en que funciona Linux, la política de seccomp-bpf solo se aplica al subproceso actual, lo que significa que no se aplica a otros subprocesos existentes, pero los subprocesos futuros heredarán la política:
- Si usas Sandbox2 en el primer modo, en el que se habilita el aislamiento en zona de pruebas antes de
execve()
, todos los subprocesos heredarán la política y no habrá problemas. Este es el modo de zona de pruebas preferido. - 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 quiere estar en zona de pruebas conSandboxMeHere()
, asegúrate de que el filtro se aplique a todos los subprocesos. De lo contrario, existe el riesgo de que se escape de la zona de pruebas: el código malicioso podría migrar de un subproceso en zona de pruebas a uno fuera de ella.
¿Cómo debo compilar mi Sandboxee?
En comparación con un ejecutable vinculado de forma estática, compilar el sandboxee en un ejecutable vinculado de forma dinámica generará un aumento significativo de las llamadas al sistema (p.ej., open
/openat
, mmap
, etc.) que deben incluirse en la lista de entidades permitidas. Todas estas llamadas al sistema adicionales son necesarias debido a la invocación del vinculador dinámico en el tiempo de ejecución para cargar las bibliotecas compartidas.
Sin embargo, si observamos los sandboxees vinculados de forma estática, si bien se deben incluir menos llamadas al sistema en la lista de entidades permitidas, también hay implicaciones de seguridad: se reduce la entropía del heap de ASLR (de 30 bits a 8 bits), lo que facilita los exploits.
Este es un dilema que se puede reducir a lo siguiente:
- Dinámico: ASLR de montón bueno, potencialmente 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 salir.
- Estático: ASLR de montón incorrecto, potencialmente más fácil de obtener la ejecución inicial del código, pero una política de zona de pruebas más eficaz, potencialmente más difícil de eludir.
Históricamente, los objetos binarios vinculados de forma estática no admitían código independiente de la posición (pie
). Además, Bazel agregaba pie
de forma predeterminada. Para poder definir un filtro de llamadas al sistema estricto, debías anular el valor predeterminado de Bazel.
Los compiladores mejoraron con el paso de los años y ahora admiten una opción static-pie
.
Con esta opción, se le indica al compilador que genere código independiente de la posición, pero, en comparación con pie
, ahora también incluye todas las bibliotecas vinculadas de forma estática. Desde el punto de vista de la seguridad, static-pie
sigue reduciendo la entropía del ASLR (de 30 bits a 14 bits), pero esto es una mejora en comparación con la situación anterior sin pie
.
Como Bazel agrega pie
de forma predeterminada y el modo estático es incompatible con él, considera usar la marca de opciones del vinculador para pasar la marca del vinculador -static-pie
a la regla cc_binary y anular el valor predeterminado:
linkstatic = 1,
linkopts=["-static-pie"],
Para ver un ejemplo de estas opciones, consulta el ejemplo static de BUILD:
static_bin.cc se vincula de forma estática con static-pie
, lo que permite tener una política de llamadas al sistema muy estricta. Esto también funciona bien para el aislamiento de procesos de ejecutables de terceros.
¿Puedo ejecutar en zona de pruebas los archivos binarios x86 de 32 bits?
Sandbox2 solo puede aislar 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 ejecutar en zona de pruebas un objeto binario x86 de 32 bits, o un objeto binario x86 de 64 bits que realiza llamadas al sistema de 32 bits (a través de int 0x80), ambos generarán un incumplimiento de la zona de pruebas que se puede identificar con la etiqueta de arquitectura [X86-32].
El motivo de este comportamiento es que los números de llamadas al sistema difieren entre las arquitecturas y, dado que la política de llamadas al sistema se escribe en la arquitectura del ejecutor, sería peligroso permitir una arquitectura diferente para Sandboxee. De hecho, esto podría llevar a permitir una llamada al sistema aparentemente inofensiva que, en realidad, significa que otra llamada al sistema más dañina podría abrir el sandbox a una fuga.
¿Existe algún límite en la cantidad de zonas de pruebas que puede solicitar un proceso de ejecutor?
Para cada instancia de Sandboxee (proceso nuevo generado desde el servidor de bifurcación), se crea un nuevo subproceso, y ahí es donde radica la limitación.
¿Un ejecutor puede solicitar la creación de más de un sandbox?
No. Existe una relación 1:1: una instancia de Executor almacena el PID de Sandboxee, administra la instancia de Comms a la instancia de Sandbox, etcétera.
¿Por qué aparece el mensaje “Function not implemented” en forkserver.cc?
Sandbox2 solo admite la ejecución en kernels razonablemente nuevos. Actualmente, nuestro límite es el kernel 3.19, aunque podría cambiar en el futuro. El motivo es que usamos funciones del kernel relativamente nuevas, incluidos los espacios de nombres del usuario y seccomp con la marca TSYNC.
Si ejecutas en producción, esto no debería ser un problema, ya que casi toda la flota ejecuta un kernel lo suficientemente nuevo. Si tienes algún problema, comunícate con nosotros.
Si ejecutas Debian o Ubuntu, actualizar el kernel es tan fácil como ejecutar:
sudo apt-get install linux-image-<RECENT_VERSION>