Visão geral do IPC do Hubris
- O Hubris usa um kernel pequeno e não dependente da aplicação, e a maior parte do código (drivers, lógica da aplicação, stack de rede etc.) existe em tarefas isoladas compiladas separadamente
- Essas tarefas podem se comunicar entre si usando um sistema de mensagens entre tarefas (IPC)
- O IPC do Hubris é composto por 3 operações centrais implementadas no kernel (RECV, SEND, REPLY)
- RECV: coleta a mensagem de maior prioridade recebida ou bloqueia até que uma mensagem chegue
- SEND: envia a mensagem e o controle para a tarefa receptora e suspende o chamador. O chamador entra em estado de espera até receber uma resposta
- REPLY: entrega uma resposta à tarefa que anteriormente usou SEND, permitindo que ela continue
Modos de falha novos e interessantes
- Como o IPC atravessa os limites entre tarefas e as tarefas do Hubris são programas compilados separadamente, é preciso ter cuidado ao fazer no IPC suposições equivalentes às que o compilador faz em chamadas de função
- Toda tarefa que atua como servidor IPC no Hubris precisa lidar com os seguintes erros potenciais:
- receber uma mensagem com a interface e o código de operação incorretos
- receber um conjunto de bytes impossível de interpretar no lugar do tipo de mensagem esperado, ou uma mensagem curta ou longa demais
- não receber a memória necessária (como memória gravável)
Em programas normais e corretos, essas situações não acontecem
- Em um programa Hubris normal, as situações mencionadas acima não acontecem
- As tarefas são conectadas entre si pela configuração do sistema de build, então é difícil confundi-las
- Cliente e servidor usam código Rust gerado, então é possível assumir que o sistema de tipos funciona além dos limites entre tarefas
O kernel não permite nenhum absurdo
- No Unix, violar as precondições de uma system call faz com que um código de erro seja retornado ao chamador, mas no Hubris a tarefa é destruída imediatamente
- O kernel do Hubris entrega erros a tarefas que violam as regras do kernel por meio do conceito de Falha Sintética (Synthetic Fault)
- No Hubris, quando ocorre uma falha de hardware ou sintética, a tarefa é interrompida imediatamente e não pode ser recuperada
O servidor também não permite nenhum absurdo
- Por meio da 13ª e mais incomum system call, REPLY_FAULT, o servidor pode entregar um erro ao cliente
- REPLY_FAULT é semelhante a REPLY, mas em vez de entregar uma mensagem e tornar a tarefa executável, entrega um erro e interrompe a tarefa
- Com REPLY_FAULT, é possível evitar tratamento desnecessário de erros de IPC. Programas normais se comportam como se problemas não pudessem acontecer, e programas anormais nem chegam a ter a chance de tratar o erro
- REPLY_FAULT oferece uma nova forma de definir e implementar erros específicos da aplicação, como regras de controle de acesso
Opinião do GN⁺
- REPLY_FAULT é um mecanismo poderoso que permite ao servidor disparar um
panic! entre processos no cliente sem cooperação do lado do cliente. Com isso, o Hubris se torna um sistema muito hostil a programas maliciosos
- A desvantagem de REPLY_FAULT é que testes de fuzzing ficam muito difíceis. Uma tarefa de engenharia do caos que gere IPCs ou system calls aleatórios é resetada imediatamente em quase qualquer operação
- No entanto, como tarefas Hubris normais não geram mensagens IPC dinamicamente, elas podem funcionar sem sequer perceber a existência de REPLY_FAULT
- Com REPLY_FAULT, o servidor pode provocar falhas aleatórias no cliente, mas a avaliação disso ainda não foi totalmente concluída
- O tratamento agressivo de erros do Hubris ajuda a encontrar erros no início do desenvolvimento e, ao contrário de códigos de erro, torna impossível ignorá-los
- Usar uma forma universal de tratar erros de IPC pode introduzir overhead desnecessário até em programas normais. REPLY_FAULT parece ser uma solução elegante para evitar isso, ao mesmo tempo em que responde com rigor a programas anormais
1 comentários
Comentários do Hacker News
Em resumo, os pontos são os seguintes:
Foi levantada a preocupação sobre se
REPLY_FAULTse propaga em cadeia e sobre as vulnerabilidades decorrentes dissoREPLY_FAULT, A também é encerradoSENDformar uma estrutura cíclica, pode até acabar encerrando a si mesmo sem quererREPLY_FAULToferece uma forma de definir e implementar erros específicos da aplicação, como controle de acessoEm sistemas em que uma única equipe escreve todo o código, eliminar clientes suspeitos pode acelerar a velocidade de iteração
O Hubris pode ser visto como um kernel que permite que o servidor execute efeitos que o cliente não consegue tratar
Hubris e Humility são tecnologias nas quais seria interessante mergulhar a fundo, mas isso é difícil por limitações de tempo e obrigações
Em uma RFC de 1º de abril sobre HTTP, foi proposto o código de status HTTP 499 com o significado de "você deveria sentir vergonha"
Citando a frase de Einstein, "tão simples quanto possível, mas não mais simples que isso", foi apontado que o projeto do Hubris viola a segunda parte
Humility é um excelente nome para um depurador
No Linux, não é possível encerrar diretamente outro programa apenas com sockets, mas com privilégios de root é possível matar outros processos ou até reiniciar a máquina
Isso entra um pouco em conflito com a sabedoria tradicional dos sistemas de rede de "seja liberal no que aceita e rigoroso no que envia"