Como compilar o compilador C a partir do zero, depois compilar o Unix / Linux a partir do zero

64

Digamos que eu trabalhe para uma grande organização de serviços fora dos EUA / Reino Unido. Usamos servidores UNIX e Linux extensivamente.

Ao ler este artigo , ele menciona que seria fácil inserir um backdoor em um compilador C, então qualquer código compilado com aquele compilador também conteria um backdoor. Agora, dados vazamentos recentes sobre o mandato da NSA / GCHQ de colocar backdoors / fraquezas em todos os métodos de criptografia, hardware e software, o compilador é agora um ponto crítico de falha. Potencialmente, todas as distribuições padrão UNIX / Linix podem ser comprometidas. Não podemos nos dar ao luxo de ter nossos sistemas, dados e dados de nossos clientes comprometidos por governos desonestos.

Dada essa informação, eu gostaria de criar um compilador confiável a partir do zero, então eu tenho uma base segura para construir, para que eu possa construir o sistema operacional e os aplicativos a partir do código-fonte usando esse compilador.

Pergunta

Qual é a maneira correta (e segura) de compilar um compilador a partir do código-fonte (um cenário aparentemente de ovo de galinha) e então compilar uma distribuição Unix / Linux confiável do zero?

Você pode assumir que eu ou outras pessoas têm a capacidade de ler e entender o código-fonte para falhas de segurança, portanto, o código-fonte será examinado antes da compilação. O que eu realmente procuro é um guia de trabalho para produzir este compilador a partir do zero com segurança e pode ser usado para compilar o kernel, outras partes do sistema operacional e aplicativos.

A pilha de segurança deve começar no nível básico, se quisermos ter alguma confiança no sistema operacional ou nos aplicativos em execução nessa pilha. Sim, eu entendo que pode haver backdoors de hardware que podem inserir algum microcódigo no compilador enquanto ele está sendo construído. Não há muito o que podemos fazer sobre isso no momento, exceto talvez usar chips não projetados nos EUA. Vamos começar essa camada para começar e suponho que eu poderia construí-la em um computador antigo, potencialmente antes que qualquer backdoor fosse inserido.

Como Bruce Schneier diz: "Para os engenheiros, eu digo isto: construímos a internet, e alguns de nós ajudaram a subvertê-la. Agora, aqueles de nós que amamos a liberdade precisam consertá-la. "

Links extras:

por David J 09.09.2013 / 04:27

4 respostas

30

AFAIK, a única maneira de ter certeza da segurança seria escrever um compilador na linguagem assembly (ou modificando o disco diretamente por você ). Só então você pode garantir que o seu compilador não esteja inserindo um backdoor - isso funciona porque você está realmente eliminando o compilador completamente.

De lá, você pode usar seu compilador do zero para fazer o bootstrap, por exemplo o conjunto de ferramentas GNU. Então você poderia usar seu conjunto de ferramentas personalizado para compilar um sistema Linux From Scratch .

Note que, para facilitar as coisas, você pode ter um segundo compilador intermediário, escrito em C (ou qualquer outra linguagem). Então você escreveria o compilador A em assembly, então reescrevesse aquele compilador em C / C ++ / Python / Brainfuck / qualquer coisa para obter o compilador B, que você compilaria usando o compilador A. Então você usaria o compilador B para compilar o gcc e seus amigos. p>     

por 09.09.2013 / 05:18
22

Uma maneira possível, embora demorasse muito tempo na prática, seria voltar às raízes. O desenvolvimento do GNU começou em 1984, e a versão original do Minix (que foi usada durante o desenvolvimento inicial do Linux para fins de bootstrap) foi lançada em 1987.

Esta resposta inteira é baseada em sua premissa de que "você ou outras pessoas têm a capacidade de ler e entender o código-fonte para falhas de segurança, portanto, o código fonte será examinado antes de compilar", e você pode confiar no resultado de tal análise. Sem isso, esta resposta é provavelmente pior do que inútil, já que você estará gastando uma enorme quantidade de tempo para absolutamente nenhum benefício.

Se você puder encontrar uma cópia do livro Minix original com o código fonte, você pode digitá-lo no livro. Compile-o e use um decompilador diferente em um sistema diferente para verificar se o compilador gera a saída binária da linguagem de máquina esperada. (O código é de apenas 12.000 linhas, presumivelmente C, por isso é demorado, mas ainda dentro de razão se você é sério sobre tal projeto.) Você pode até escrever seu próprio desmontador; isso não deve ser muito difícil.

Pegue as versões mais antigas dos utilitários GNU em que você pode possivelmente ter acesso (como aqueles presumivelmente têm menos código e menos dependências para bibliotecas externas), vá pelo código, construa para o Minix (isso pode levar algum trabalho, o que você absolutamente quer evitar é fazer ajustes no código-fonte, porque isso tornará a adição de correções mais propensa a erros) e passar por um ciclo similar de verificação de desmontagem para as ferramentas GNU. Nesse ponto, você confia no sistema operacional e no toolchain, portanto, só precisa passar pelo código-fonte no patchset (qualquer coisa que não esteja no patchset já é confiável), mas as ferramentas ainda serão muito primitivas e rudimentares em relação ao que você usa para hoje. Não espere nada mais do que a funcionalidade mais básica das ferramentas do sistema, por exemplo. Agora transfira tudo para e migre para o Minix e comece a aplicar patches, uma versão de cada vez, reconstruindo tudo afetado entre cada versão e usando a nova versão na próxima vez. Leia muitos XKCD.

Em algum ponto, você terá um sistema que pode compilar e inicializar uma versão inicial do kernel do Linux, assim como foi feito no início dos anos 90, quando o Linux começou a ganhar força entre os hackers. Sugiro migrar para o Linux nesse ponto (reconstruir as bibliotecas do sistema e o toolchain contra o Linux, criar o kernel do Linux, inicializar no Linux e possivelmente reconstruir o kernel do Linux e o GNU toolchain no Linux; a última prova de que o sistema agora é auto- hospedagem), mas isso depende muito de você. Continue verificando patches, corrigindo o kernel, bibliotecas e ferramentas básicas do GNU e reconstruindo até chegar às versões modernas.

É quando você tem um sistema operacional e compilador confiáveis que podem ser usados para construir softwares modernos. Até então, você pode seguir, por exemplo o Linux From Scratch orienta a construção de um sistema capaz de executar tarefas úteis .

Em nenhum momento o sistema "compilador" pode ser conectado a uma rede de qualquer maneira (incluindo como uma VM em um host em rede); você arriscaria penetração através de qualquer componente capaz de rede, incluindo o kernel. Se você está preocupado com um ataque do compilador Thompson , você deve esperar que qualquer host VM também pode estar comprometido. Use o sneakernet para obter o código-fonte e os binários do host físico no qual você está compilando as coisas. Esperar problemas ao obter arquivos dentro e fora do sistema pelo menos antes de chegar ao ponto em que o suporte ao armazenamento em massa USB foi implementado. Se você é realmente paranóico, imprima listagens de código fonte e digite-as manualmente (e espere que o driver da impressora e a impressora não tenham código similar em elas ), ou leia código em um monitor de computador e digite-o em outro computador fisicamente ao lado, mas não conectado a ele.

Sim, isso levará muito de tempo. Mas a vantagem dessa abordagem é que cada etapa é incremental, o que significa que seria muito mais difícil para qualquer coisa mal-intencionada passar, a menos que seja gradualmente introduzida em um período de muitas versões; isso porque o conjunto de alterações em cada etapa é comparativamente pequeno e, portanto, muito mais fácil de examinar. Compare o patchset com o changelog e verifique se você pode determinar exatamente qual entrada do changelog corresponde a cada alteração no código-fonte. Novamente, isso supõe que você tem a habilidade (possivelmente através de alguém em quem confia) para verificar se tais mudanças não foram inseridas na base de código, mas ele deve ficar o mais próximo possível de um sistema confiável. somente a abordagem except-firmware pode.

    
por 09.09.2013 / 11:15
9

Se você precisa de um compilador confiável, pode dar uma olhada no trabalho acadêmico, como o projeto compcert . É um compilador construído pelo INRIA (um laboratório público de TI francês) projetado para ser '' certificado '', ou seja, para produzir um executável semanticamente perfeitamente equivalente ao código (e, claro, foi comprovado matematicamente).

    
por 09.09.2013 / 10:00
2

Embora a criação manual do seu próprio compilador como ponto de partida seja a mais segura, outra opção é instalar um sistema a partir de um CD de instalação de 5 (ou 10) anos que você confie que foi criado antes da existência desses exploits. Em seguida, use isso como base para compilar a nova fonte auditada.

    
por 09.09.2013 / 09:35