Proxecto para portar o mecanismo de illamento de promesas a Linux

O autor da biblioteca C estándar Cosmopolitan e da plataforma Redbean anunciou a implementación do mecanismo de illamento pledge() para Linux. Pledge foi desenvolvido orixinalmente polo proxecto OpenBSD e permítelle prohibir selectivamente que as aplicacións accedan ás chamadas do sistema non utilizadas (unha especie de lista branca de chamadas ao sistema está formada para a aplicación, e outras chamadas están prohibidas). A diferenza dos mecanismos de restrición de acceso de chamadas ao sistema dispoñibles en Linux, como seccomp, o mecanismo de promesa foi deseñado orixinalmente para ser o máis fácil de usar posible.

A iniciativa fallida de illar aplicacións no contorno base de OpenBSD mediante o mecanismo systrace mostrou que o illamento a nivel de chamadas individuais do sistema era demasiado complexo e levaba moito tempo. Como alternativa, propúxose un compromiso, que permitiu crear regras de illamento sen entrar en detalles e manipular clases de acceso xa preparadas. Por exemplo, as clases ofrecidas son stdio (entrada/saída), rpath (ficheiros de só lectura), wpath (ficheros de escritura), cpath (crear ficheiros), tmppath (traballar con ficheiros temporais), inet (sockets de rede), unix ( sockets unix), dns (resolución DNS), getpw (acceso de lectura á base de datos de usuarios), ioctl (chamada ioctl), proc (xestion de procesos), exec (lanzamento de procesos) e id (xestion de dereitos de acceso).

As regras para traballar con chamadas ao sistema especifícanse en forma de anotacións, incluíndo unha lista de clases permitidas de chamadas ao sistema e unha matriz de camiños de ficheiros onde se permite o acceso. Despois de construír e lanzar a aplicación modificada, o núcleo asume o traballo de supervisar o cumprimento das regras especificadas.

Estase a desenvolver unha implementación separada de pledge para FreeBSD, que se distingue pola capacidade de illar aplicacións sen facer cambios no seu código, mentres que en OpenBSD a chamada pledge está dirixida a unha estreita integración co ambiente base e a engadir anotacións ao código de cada un. aplicación.

Os desenvolvedores do port de compromiso para Linux tomaron o exemplo de FreeBSD e, en lugar de facer cambios no código, prepararon unha utilidade complementaria pledge.com que che permite aplicar restricións sen cambiar o código da aplicación. Por exemplo, para executar a utilidade curl con acceso só ás clases de chamadas do sistema stdio, rpath, inet e threadstdio, só tes que executar “./pledge.com -p 'stdio rpath inet thread' curl http://example.com”.

A utilidade de promesa funciona en todas as distribucións de Linux que comezan con RHEL6 e non require acceso root. Adicionalmente, baseándose na biblioteca cosmopolita, ofrécese unha API para xestionar restricións no código do programa en linguaxe C, que permite, entre outras cousas, crear enclaves para restrinxir selectivamente o acceso en relación a determinadas funcións da aplicación.

A implementación non require cambios no núcleo: as restricións de promesas tradúcense a regras SECCOMP BPF e procésanse mediante o mecanismo de illamento nativo de chamadas do sistema Linux. Por exemplo, a chamada pledge("stdio rpath", 0) converterase nun filtro BPF static 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_ALU | BPF_ALU | 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_RET | BPF_JMP | SECCOMP_RET_ALLOW), /*L13*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)), /*L14*/ /* seguinte filtro */ };

Fonte: opennet.ru

Engadir un comentario