Projeto para portar o mecanismo de isolamento de promessas para Linux

O autor da biblioteca C padrão Cosmopolitan e da plataforma Redbean anunciou a implementação do mecanismo de isolamento commit() para Linux. O Pledge foi originalmente desenvolvido pelo projeto OpenBSD e permite proibir seletivamente o acesso de aplicativos a chamadas de sistema não utilizadas (uma espécie de lista branca de chamadas de sistema é formada para o aplicativo e outras chamadas são proibidas). Ao contrário dos mecanismos de restrição de chamadas de sistema disponíveis no Linux, como o seccomp, o mecanismo de promessa foi originalmente projetado para ser o mais simples possível.

A iniciativa fracassada de isolar aplicativos no ambiente base do OpenBSD usando o mecanismo systrace mostrou que o isolamento no nível de chamadas de sistema individuais era muito complexo e demorado. Como alternativa, foi proposto um compromisso que possibilitou a criação de regras de isolamento sem entrar em detalhes e manipular classes de acesso prontas. Por exemplo, as classes oferecidas são stdio (entrada/saída), rpath (arquivos somente leitura), wpath (gravar arquivos), cpath (criar arquivos), tmppath (trabalhar com arquivos temporários), inet (soquetes de rede), unix ( soquetes unix), dns (resolução de DNS), getpw (acesso de leitura ao banco de dados do usuário), ioctl (chamada ioctl), proc (gerenciamento de processos), exec (lançamento de processos) e id (gerenciamento de direitos de acesso).

As regras para trabalhar com chamadas do sistema são especificadas na forma de anotações, incluindo uma lista de classes permitidas de chamadas do sistema e uma matriz de caminhos de arquivos onde o acesso é permitido. Depois de construir e lançar o aplicativo modificado, o kernel assume o trabalho de monitorar a conformidade com as regras especificadas.

Uma implementação separada de promessa está sendo desenvolvida para o FreeBSD, que se distingue pela capacidade de isolar aplicativos sem fazer alterações em seu código, enquanto no OpenBSD a chamada de promessa visa a integração estreita com o ambiente base e a adição de anotações ao código de cada aplicativo.

Os desenvolvedores da porta de promessa para Linux pegaram o exemplo do FreeBSD e, em vez de fazer alterações no código, prepararam um utilitário complementar commit.com que permite aplicar restrições sem alterar o código do aplicativo. Por exemplo, para executar o utilitário curl com acesso apenas às classes de chamada de sistema stdio, rpath, inet e threadstdio, basta executar “./pledge.com -p ‘stdio rpath inet thread’ curl http://example.com”.

O utilitário commit funciona em todas as distribuições Linux começando com RHEL6 e não requer acesso root. Além disso, com base na biblioteca cosmopolita, é fornecida uma API para gerenciamento de restrições no código do programa na linguagem C, que permite, entre outras coisas, criar enclaves para restringir seletivamente o acesso em relação a determinadas funções da aplicação.

A implementação não requer alterações no kernel - as restrições de promessa são traduzidas em regras SECCOMP BPF e processadas usando o mecanismo nativo de isolamento de chamadas do sistema Linux. Por exemplo, a chamada commit("stdio rpath", 0) será convertida em um 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_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*/ /* próximo filtro */ };

Fonte: opennet.ru

Adicionar um comentário