¿Cómo restringir dlopen () desde o hacia ciertas rutas?

6

Si quiero deshabilitar la ejecución de programas en un sistema de archivos, puedo usar la opción de montaje noexec .

Sin embargo, esto no funciona con las bibliotecas dinámicas cargadas a través de dlopen() . Entonces, ¿cuál es la manera de hacerlo con nacl o seccomp? (esto es para sandboxing de bytecode no confiable, no quiero que los usuarios puedan ejecutar bibliotecas compartidas que subieron)

Al mismo tiempo, las bibliotecas como gconv deben poder ejecutar sus módulos .so .
fork () ing o exec () uting otros programas programáticamente ya está deshabilitado.

    
pregunta user2284570 14.08.2016 - 19:13
fuente

1 respuesta

-1
  

Sin embargo, esto no funciona con las bibliotecas dinámicas.

Funciona para bibliotecas dinámicas. Si un objeto compartido se encuentra en una partición que está montada con la opción noexec, no se puede cargar, de lo contrario noexec sería bastante inútil.

$ grep -E '/tmp |ext4' /proc/mounts
/dev/mapper/root_crypt / ext4 rw,nodev,noatime,data=ordered 0 0
tmpfs /tmp tmpfs rw,nosuid,nodev,noexec,noatime,size=2031200k 0 0
$ cat > main.c
#include <stdio.h>

void main(void)
{
        printf("%d\n", getpid());
}
$ gcc -o main main.c
$ ./main
4950
$ cat > shared.c
int getpid(void)        
{
        return 1;
}
$ gcc -shared -fPIC -o shared.so shared.c
$ LD_PRELOAD=./shared.so ./main
1
$ mv shared.so /tmp
$ LD_PRELOAD=/tmp/shared.so ./main
ERROR: ld.so: object '/tmp/shared.so' from LD_PRELOAD cannot be preloaded (failed to map segment from shared object): ignored.
4978

Si desea usar seccomp para evitar la ejecución de objetos compartidos no confiables, puede hacerlo restringiendo las llamadas a mmap() , mprotect() y, obviamente, execve() . Asegúrese de que el proceso no pueda asignar nada con PROT_EXEC . La restricción de archivos no es suficiente, ya que cualquier dato arbitrario puede pasarse a mmap() a través de un descriptor de archivo, y mprotect() puede cambiar los permisos de páginas arbitrarias de memoria para hacerlos ejecutables. Además, dado que este ejemplo es una lista negra en lugar de una lista blanca, también tendrá que denegar el acceso a algunos argumentos ptrace() , ya que se pueden usar para salir de una caja de arena seccomp.

rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mmap), 1,
    SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
if (rc == -1)
    goto out;

rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCESS), SCMP_SYS(mprotect), 1,
    SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));
if (rc == -1)
    goto out;

rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCESS), SCMP_SYS(execve), 0);
if (rc == -1)
    goto out;

rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1,
    SCMP_A0(SCMP_CMP_EQ, PTRACE_POKEUSER));
if (rc == -1)
    goto out;

rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1,
    SCMP_A0(SCMP_CMP_EQ, PTRACE_SETREGS));
if (rc == -1)
    goto out;

rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(ptrace), 1,
    SCMP_A0(SCMP_CMP_EQ, PTRACE_SETREGSET));
if (rc == -1)
    goto out;

Probablemente hay formas de omitir este fragmento de fragmento de compilación en el que no he pensado, así que esto es solo para darte una idea de lo que se necesita.

Nunca he usado NaCl, así que no puedo decir cómo restringirías la ejecución con él.

    
respondido por el landmark 15.08.2016 - 09:27
fuente

Lea otras preguntas en las etiquetas