Como proibir o acesso à memória física no Linux?

3

Eu estou em um sistema embarcado (Zynq da Xilinx. Ele usa o ARMv7, Cortex-A9) e roda o Linux. Preciso garantir que nenhum acesso a um determinado intervalo de memória física seja ever efetuado acidentalmente pelo espaço do kernel ou pelo usuário. Eu posso sinalizar, abortar dados ou qualquer outra coisa, mas essa tentativa de hardware não deve ir além da MMU.

No modo bare-metal e no U-Boot, tenho acesso direto à localização da TLB e posso restringir o acesso à memória em um nível de hardware configurando a MMU para abortar dados caso ocorra qualquer acesso de leitura ou gravação. Eu quero fazer isso no Linux, onde até mesmo um mmap () lançaria uma anulação de dados.

O raciocínio:

No Zynq, 2 GB de espaço de endereço são alocados para um intervalo que pode nunca responder em um nível de hardware. O protocolo AXI / AMBA da ARM diz que um host nunca pode "desistir" em uma tentativa de acessar um endereço, mesmo que não exista nada. Se eu de-referência de um ponteiro onde não há hardware, o chip inteiro trava.

Eu sei que posso "simplesmente não dar sudo" ou "apenas escrever bons drivers", mas isso é antes mesmo desse nível. Eu quero, no início do boot, configurar o TLB da MMU para abortar completamente os dados se o meu super usuário fizer algum código ruim. Eu prefiro não hackear boot.S, mas modifique o TLB diretamente, então use a API para liberá-lo.

    
por IDLacrosseplayer 24.06.2015 / 03:27

1 resposta

3

O kernel do Linux tem opções para restringir quais intervalos de endereços físicos ele usará como RAM, mas isso não impedirá que drivers com bugs ou acesso através de /dev/mem escapem desses intervalos. Você não ganhará nada com a modificação da configuração da MMU durante o estágio de inicialização, porque o kernel assumirá o controle da MMU depois disso, de qualquer maneira. Se você quer ter certeza absoluta de que o sistema Linux não irá acessar certos intervalos de memória, você precisa de algum controle externo.

Sua arquitetura oferece uma maneira de restringir o que o kernel do Linux pode acessar: TrustZone (ou, mais precisamente, TrustZone plus o firewall de memória) ¹. Eu duvido que você encontre uma solução pronta para o que você está fazendo, você precisará fazer um pouco de codificação. Felizmente, a documentação sobre o TrustZone no Zync está disponível. Aqui está a ideia básica:

  • O processador inicializa no modo S. Configure os registros de controle TrustZone para desativar o acesso não seguro nesse intervalo de 2 GB.
  • Depois disso, mude para o modo NS e se ramifique para o bootloader normal.
  • Se o Linux tentar acessar o intervalo de 2GB bloqueado, a solicitação será bloqueada antes de atingir o barramento de memória e, em vez disso, acionará um aborto (anulação imprecisa, se houver armazenamento em cache ou pré-busca).

¹ Os recentes processadores ARM oferecem uma outra maneira, que é executar um hypervisor, mas que não está disponível em um Cortex-A9.

    
por 25.06.2015 / 04:14