Proyecto para migrar el mecanismo de aislamiento de compromiso a Linux

El autor de la biblioteca C estándar Cosmopolitan y la plataforma Redbean ha anunciado la implementación del mecanismo de aislamiento promesa() para Linux. Pledge fue desarrollado originalmente por el proyecto OpenBSD y le permite prohibir selectivamente que las aplicaciones accedan a llamadas al sistema no utilizadas (se forma una especie de lista blanca de llamadas al sistema para la aplicación y otras llamadas están prohibidas). A diferencia de los mecanismos de restricción de llamadas al sistema disponibles en Linux, como seccomp, el mecanismo de compromiso se diseñó originalmente para ser lo más simple posible.

La fallida iniciativa de aislar aplicaciones en el entorno base de OpenBSD utilizando el mecanismo systrace demostró que el aislamiento a nivel de llamadas individuales al sistema era demasiado complejo y requería mucho tiempo. Como alternativa, se propuso un compromiso que permitía crear reglas de aislamiento sin entrar en detalles ni manipular clases de acceso ya preparadas. Por ejemplo, las clases que se ofrecen son stdio (entrada/salida), rpath (archivos de solo lectura), wpath (escribir archivos), cpath (crear archivos), tmppath (trabajar con archivos temporales), inet (sockets de red), unix ( sockets Unix), dns (resolución DNS), getpw (acceso de lectura a la base de datos del usuario), ioctl (llamada ioctl), proc (gestión de procesos), exec (inicio de procesos) e id (gestión de derechos de acceso).

Las reglas para trabajar con llamadas al sistema se especifican en forma de anotaciones, incluida una lista de clases permitidas de llamadas al sistema y una serie de rutas de archivos a las que se permite el acceso. Después de compilar y ejecutar la aplicación modificada, el kernel asume el trabajo de monitorear el cumplimiento de las reglas especificadas.

Para FreeBSD se está desarrollando una implementación separada del compromiso, que se distingue por la capacidad de aislar aplicaciones sin realizar cambios en su código, mientras que en OpenBSD el compromiso tiene como objetivo una estrecha integración con el entorno base y agregar anotaciones al código de cada uno. solicitud.

Los desarrolladores del puerto de compromiso para Linux tomaron el ejemplo de FreeBSD y, en lugar de realizar cambios en el código, prepararon una utilidad complementaria compromiso.com que le permite aplicar restricciones sin cambiar el código de la aplicación. Por ejemplo, para ejecutar la utilidad curl con acceso solo a las clases de llamadas al sistema stdio, rpath, inet y threadstdio, simplemente ejecute “./pledge.com -p 'stdio rpath inet thread' curl http://example.com”.

La utilidad de compromiso funciona en todas las distribuciones de Linux a partir de RHEL6 y no requiere acceso de root. Además, basándose en la biblioteca cosmopolitan, se proporciona una API para gestionar restricciones en el código del programa en lenguaje C, que permite, entre otras cosas, crear enclaves para restringir selectivamente el acceso a determinadas funciones de la aplicación.

La implementación no requiere cambios en el kernel: las restricciones de compromiso se traducen en reglas SECCOMP BPF y se procesan utilizando el mecanismo de aislamiento de llamadas del sistema nativo de Linux. Por ejemplo, la llamada promesa("stdio rpath", 0) se convertirá en un filtro BPF estático const struct sock_filter kFilter[] = { /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, syscall, 0, 14 - 1 ), / * L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])), /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 4 - 3, 0), /* L3* / BPF_JUMP( BPF_JMP | BPF_JEQ | BPF_K, 10, 0, 13 - 4), /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])), /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~0x80800), /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 8 - 7, 0), /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 13 - 8) , /* L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])), /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 12 - 10, 0), /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 6, 12 - 11, 0), /*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 17, 0, 13 - 11), /*L12*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), /*L13*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)), /*L14*/ /* siguiente filtro */ };

Fuente: opennet.ru

Añadir un comentario