Quais são as possíveis armadilhas de ter um kernel mínimo que executa código gerenciado?

14

Suponha que eu queira construir um sistema operacional baseado em um kernel inferior nativo muito pequeno que atue como um interpretador de código gerenciado / tempo de execução e um kernel superior maior compilado em uma linguagem de máquina não nativa (Java bytecode, CIL etc.). Exemplos de sistemas operacionais semelhantes seriam Singularity e Cosmos .

Que armadilhas e desafios de desenvolvimento existem ao escrever um sistema operacional com esse tipo de infraestrutura em contraste com uma solução puramente nativa?

Adam Maras
fonte

Respostas:

8

Dependendo do idioma, pode haver muitos desafios de desenvolvimento:

  1. Ponteiros: se um idioma não tiver ponteiros, será um desafio realizar tarefas relativamente fáceis. Por exemplo, você pode usar ponteiros para gravar na memória VGA para imprimir na tela. No entanto, em uma linguagem gerenciada, você precisará de algum tipo de "plug" (do C / C ++) para fazer o mesmo.

  2. Montagem: um sistema operacional sempre precisa de alguma montagem. Idiomas como C #, Java etc. não funcionam tão bem com isso, ao contrário do C / C ++. Em C ou C ++, você também pode ter um assembly embutido, o que é muito, muito útil para muitas tarefas. Existem MUITOS casos em que isso é necessário (exemplos em x86): carregamento de um GDT, carregamento de um IDT, ativação de paginação, configuração de IRQs etc.

  3. Controle: se você estiver usando algo como o Cosmos, não terá controle total. O Cosmos é um micro-kernel e essencialmente "inicia" o seu "kernel". Você pode implementar algo como o Cosmos do zero, se realmente quiser, no entanto, isso pode levar muito, muito tempo.

  4. Sobrecarga: com idiomas gerenciados, há MUITA sobrecarga em comparação com C ou mesmo C ++. Coisas como o Cosmos precisam implementar muitas coisas antes que até um kernel hello world C # possa ser executado. Em C, você está pronto para começar, nenhuma configuração real é necessária. No C ++, há apenas algumas coisas que precisam ser implementadas para usar alguns dos recursos do C ++.

  5. Estruturas: No C / C ++, existem estruturas que muitas linguagens gerenciadas não possuem e, portanto, você precisa implementar alguma maneira de ter algo como uma estrutura. Por exemplo, se você deseja carregar uma IDT (tabela de descritores de interrupção), em C / C ++, é possível criar uma estrutura (com um atributo compactado) e carregá-la usando a instrução x86 ASM lidt . Em um idioma gerenciado, isso é muito mais difícil de fazer ...

Idiomas gerenciados, em termos de sintaxe, são mais fáceis, no entanto, pois muitas coisas relacionadas ao sistema operacional muitas vezes não são muito adequadas. Isso não significa que eles não possam ser usados, no entanto, algo como C / C ++ é frequentemente recomendado.

mmk
fonte
Essa resposta é bem fraca. Quais são as "tarefas relativamente fáceis" que você não pode fazer sem ponteiros (excluindo uma base minúscula)? Quais são as peças que precisam de montagem? Que controle você falta? Em que você baseia sua declaração sobre despesas gerais? Por que você não pode ter estruturas em um idioma gerenciado?
Gilles 'SO- stop be evil'
1. Não há razão para que um idioma gerenciado não ofereça a capacidade de acessar a memória VGA, é apenas o mapeamento / desmapeamento que teria que ser fornecido como um primitivo (um primitivo de gerenciamento de memória). 2. Algumas alternâncias de tarefas (por exemplo, salvar registros) geralmente precisam ser feitas como código de montagem, mas são muito localizadas, não é um argumento contra ter 99% do SO em um idioma gerenciado. Manipular a MMU é uma primitiva de gerenciamento de memória. 4. C também precisa de configuração (configure uma pilha e pilha); os idiomas gerenciados precisam de um pouco mais de configuração, mas não há diferença qualitativa.
Gilles 'SO- stop be evil'
@Gilles, a questão é quais são os desafios de desenvolvimento para o uso de uma linguagem gerenciada. Esses são desafios de desenvolvimento, no entanto, você ainda pode superar com êxito esses desafios ... #
22714
5

Ouvi dizer (por um pesquisador que trabalha em uma técnica concorrente de microkernel ) que pouco se sabe sobre como avaliar a segurança de sistemas extensíveis por meio de código gerenciado.

O problema é que os tipos de bugs que podem causar uma falha na segurança são muito diferentes do que os pesquisadores de segurança estão acostumados. Em um microkernel tradicional, todos os drivers e outras subpartes do kernel são isolados um do outro, executando-os em diferentes espaços de endereço. Em um microkernel em que o isolamento é implementado por meio de código gerenciado de verificação de tipo, você evita as enormes despesas gerais de trocar espaços de endereço toda vez que precisar usar um sub-serviço, mas a desvantagem é que agora é mais difícil avaliar o mecanismo de isolamento.

Qualquer parte específica do kernel (digamos, um driver de dispositivo) escrita no idioma gerenciado é segura se e somente se o verificador de tipos indicar que o driver é seguro e que o verificador de tipos não possui bugs. Portanto, o verificador de tipos faz parte do núcleo do kernel. Na prática, parece que os verificadores de tipo são consideravelmente maiores e mais complicados do que os núcleos tradicionais de microkernel. Isso significa que a superfície de ataque é potencialmente maior.

Não sei se as técnicas tradicionais de isolamento de micro-kernel ou técnicas de isolamento baseadas em código gerenciado são realmente mais ou menos confiáveis. Há um problema de inicialização aqui: até que as técnicas de isolamento de código gerenciado sejam amplamente usadas, não saberemos com que frequência elas são inseguras. Mas, sem saber quão inseguras elas são, é difícil implantá-las em situações críticas à segurança.

Lógica Errante
fonte
Esse é um ponto excelente.
Adam Maras
Acho esses argumentos muito estranhos. (Concedido, posso ser influenciado pela minha formação em métodos formais, mas essa não é a única base para minha opinião.) Um verificador de datilografia não é tão complexo, comparado com um microkernel mais uma MMU. Por exemplo, o microkernel da Coq tem cerca de 14kLoC de OCaml - maior que um microkernel, mas não tanto assim, e escrito em uma linguagem menos propensa a erros do que a maioria dos kernels (sem C ou assembler). Damas de tipo não são suscetíveis a condições de corrida, que são uma classe particularmente sutil de bugs.
Gilles 'SO- stop be evil'
O código gerenciado oferece uma oportunidade melhor de lidar com determinada classe de bugs; por exemplo, a análise do fluxo de informações pode provar a ausência de canais laterais (é provável que dê muito trabalho e não sei até que ponto isso foi feito, mas é factível em princípio), enquanto o isolamento de hardware apenas permite testar os canais laterais em que você pensou.
Gilles 'SO- stop be evil' (
No lado prático, várias máquinas virtuais que fornecem isolamento foram certificadas no EAL5 e acima. Aqui estão dois exemplos que você pode ter em sua carteira, se for europeu, porque eles são usados ​​em cartões inteligentes, como cartões de crédito: MULTOS , plataforma aberta Java Card . Na comunidade de avaliação de segurança, ouvi muitas dúvidas de que o isolamento da MMU poderia ir além do EAL2.
Gilles 'SO- stop be evil'