¿Puedo usar subprocesos?
Sí, los subprocesos son compatibles con Sandbox2.
Todos los subprocesos deben estar en zona de pruebas
Debido a la forma en que funciona Linux, la política de seccomp-bpf solo se aplica al subproceso actual. Esto significa que la política no se aplica a otros subprocesos existentes, pero los subprocesos futuros la heredarán:
- Si usas Sandbox2 en el primer
modo
en el que se habilita la zona de pruebas antes de
execve(), todos los subprocesos heredarán la política y no habrá ningún 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 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 que no lo esté.
¿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 montón ASLR (de 30 bits a 8 bits), lo que facilita las vulnerabilidades.
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 romper.
- Estático: ASLR de montón malo, 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 romper.
Históricamente, los objetos binarios vinculados de forma estática no admitían código independiente de la posición (pie). Además, Bazel agregó pie de forma predeterminada. Para poder definir un filtro de llamadas al sistema ajustado, debías anular el valor predeterminado de Bazel.
Los compiladores mejoraron con los años y ahora admiten una opción static-pie.
Con esta opción, se le indica a un 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 aún reduce la entropía ASLR (de 30 bits a 14 bits), pero esto es una mejora con respecto a la situación anterior
sin pie.
Como Bazel agrega pie de forma predeterminada y la estática es incompatible con ella, considera
usar la marca de opciones del vinculador para pasar la marca del vinculador -static-pie a la
cc_binary
regla y anular el valor predeterminado:
linkstatic = 1,
linkopts=["-static-pie"],
Para obtener un ejemplo de estas opciones, consulta el
ejemplo estático
BUILD:
static_bin.cc está vinculado de forma estática con static-pie, lo que permite
tener una política de llamadas al sistema muy ajustada. Esto también funciona bien para la zona de pruebas de objetos binarios de terceros.
¿Puedo usar la zona de pruebas de objetos binarios x86 de 32 bits?
Sandbox2 solo puede usar la zona de pruebas de 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 usar la zona de pruebas de 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 una violación 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, como la política de llamadas al sistema está escrita en la arquitectura del ejecutor, sería peligroso permitir una arquitectura diferente para el Sandboxee. De hecho, esto podría permitir una llamada al sistema aparentemente inofensiva que, de hecho, significa que otra llamada al sistema más dañina podría abrir la zona de pruebas a una vulnerabilidad.
¿Hay límites en la cantidad de zonas de pruebas que puede solicitar un proceso de ejecutor?
Para cada instancia de Sandboxee (proceso nuevo generado desde el forkserver), se crea un subproceso nuevo, ahí es donde se encuentra la limitación.
¿Puede un ejecutor solicitar la creación de más de una zona de pruebas?
No. Hay una relación de 1:1: una instancia de ejecutor almacena el PID del Sandboxee, administra la instancia de Comms a la instancia de Sandbox, etcétera.
¿Por qué recibo el mensaje “Función no implementada” dentro de forkserver.cc?
Sandbox2 solo admite la ejecución en kernels razonablemente nuevos. Nuestro límite actual 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 de 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 con esto, comunícate con nosotros.
Si ejecutas en Debian o Ubuntu, actualizar tu kernel es tan fácil como ejecutar lo siguiente:
sudo apt-get install linux-image-<RECENT_VERSION>