Como mmap ' ing / dev / mem funciona apesar de ser do modo não privilegiado?
On Fevereiro 9, 2021 by adminPelo que entendi, os programas de espaço do usuário são executados no modo sem privilégios e, portanto, não têm acesso direto à memória ou E / S.
Então, como exatamente podemos acessar diretamente a memória ou os locais de E / S quando fazemos mmap / dev / mem em programas de espaço do usuário?
Por exemplo:
int fd = 0; u8 leds = 0; fd = open("/dev/mem", O_RDWR|O_SYNC); leds = (u8 *)mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x80840000);
Este é um hack muito comumente usado em dispositivos embutidos.
Agora, a variável leds
pode ser usada instantaneamente para acessar qualquer dispositivo que possa estar presente em 0x80840000.
Não usaremos mais nenhuma chamada de sistema para acessar esse endereço.
Mesmo algo como
leds[0x20] = val;
funcionaria.
Mas operações privilegiadas, como ler / gravar diretamente de / para um endereço de E / S devem ser possíveis apenas colocando o processador no modo privilegiado por meio de uma chamada de sistema.
Fonte .
Comentários
Resposta
Permitindo acesso a /dev/mem
por processos sem privilégios seria realmente um problema de segurança e não deveria ser permitido.
No meu sistema, ls -l /dev/mem
se parece com isto:
crw-r----- 1 root kmem 1, 1 Sep 8 10:12 /dev/mem
Assim, root
podem ler e escrever, membros da kmem
group (do qual não há nenhum) pode lê-lo, mas não pode escrever, e todos os outros não podem abri-lo. Portanto, isso deve ser seguro.
Se o seu /dev/mem
for parecido com o meu, seu processo sem privilégios nem deveria ter sido capaz de abrir o arquivo, muito menos mmap
isso.
Verifique as permissões de /dev/mem
em seu sistema para ter certeza de que estão seguras!
Comentários
- Mas supondo que estou fazendo isso como root … Isso significa que um processo executado pelo root obtém o kernel privilégios de acesso de nível?
- Bem, se você ' estiver fazendo isso como root, terá acesso a tudo. Eu ' não tenho certeza do que você quer dizer com " privilégios de acesso no nível do kernel ", mas O root pode certamente fazer qualquer coisa que quiser, de uma forma ou de outra (em particular, por exemplo, criando e carregando dinamicamente um novo módulo do kernel).
- Sim, isso ' está correto: quando você mapeia um arquivo, você depois consegue ler & e escrever o arquivo sem o uso de nenhuma chamada ststem. Isso ' é verdadeiro se você ' mapeou um arquivo de disco regular ou um dispositivo especial como
/dev/mem
. Se preferir, você pode abrir/dev/mem
e emitir chamadas de sistemaread()
ewrite()
. Então você não estaria enviando E / S sem o uso de chamadas de sistema. O resultado final é o mesmo, mas se você tiver muitas pequenas E / S para fazer,mmap()
e o acesso direto provavelmente terão um desempenho melhor especificamente porque você não ' t preciso de chamadas de sistema! Isso também é verdade para arquivos normais! - @ Stark07 Acho que você ' não entendeu o ponto. Os
mmap
(e/dev/mem
) em si NÃO fornecem acesso direto ao memória do sistema, e é impossível fazer isso no Anel 4. O que ele faz é apenas mapear um arquivo (ou recurso) para um endereço virtual específico no processo de chamada, assim como o que acontece quando um programa é carregado /exec
ed (neste caso, a imagem do programa émmap
ed para a memória virtual). - TL; DR Um processo sem privilégios não tem acesso direto ao recurso do sistema, mas pode ter quando esse recurso é mapeado para seu espaço de endereço virtual . Não ' s nenhuma diferença entre acessar sua pilha / heap / rodata / qualquer e acessar a memória do kernel – eles eventualmente acessam a memória física real, enquanto o último caso apenas acontece de estar sob o controle ' do programa.
Resposta
Os endereços visíveis para um processo do usuário (seja executando como root ou um usuário sem privilégios) são endereços virtuais, que são mapeados para endereços físicos pela MMU por meio das tabelas de página. A configuração das tabelas de página é uma operação privilegiada e só pode ser executada pelo código do kernel; no entanto, uma vez que as tabelas de página são definidas, o acesso à memória é permitido no modo de usuário.
Concretamente, seu código usa mmap
para solicitar que o kernel configure o tabelas de páginas para permitir o acesso a um determinado intervalo de memória física. O kernel verifica os privilégios do processo (ele tem acesso de leitura / gravação a /dev/mem
) e configura as tabelas de página para permitir o acesso à memória física.
Resposta
O valor de leds
é um endereço virtual. Contanto que esteja no espaço do usuário do processo atual, o processo pode acessá-lo diretamente por meio de instruções como leds[0] = val
sem ter que estar no modo privilegiado, não importa onde na RAM este endereço virtual esteja mapeado
*
na declaração deleds
, mas esse ' é apenas um código, nenhuma evidência de que isso realmente funcione como um usuário sem privilégios; em minha experiência (limitada), tudo funciona como root em dispositivos incorporados.root
tem muitos privilégios, que incluem a permissão para substituir o tradicional permissões do sistema de arquivos. Alguns " arquivos " são realmente de acesso a dispositivos (como disco ou memória), que estão fora dos limites para usuários regulares. Nãoroot
. Masroot
é executado no espaço do usuário , então não ' desfruta de todos os privilégios do modo de sistema (execute instruções privilegiadas, principalmente).