Como o mmap'ing / dev / mem funciona apesar de ser de modo não privilegiado?

4

No que diz respeito ao meu entendimento, os programas espaciais do usuário são executados no modo não privilegiado 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 o mmap / dev / mem nos 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 embarcados.

Agora, a variável leds pode ser usada rapidamente 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 / escrever diretamente para / de 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 .

    
por Stark07 14.11.2014 / 11:34

3 respostas

6

Permitir o acesso a /dev/mem por processos sem privilégios seria de fato um problema de segurança e não deveria ser permitido.

No meu sistema, ls -l /dev/mem é assim:

crw-r----- 1 root kmem 1, 1 Sep  8 10:12 /dev/mem

Portanto, root pode ler e escrever, membros do grupo kmem (dos quais não há nenhum) podem lê-lo, mas não escrevê-lo, e todos os outros não conseguem abri-lo. Então, isso deve ser seguro.

Se o seu /dev/mem é parecido com o meu, seu processo sem privilégios não deveria ter sido capaz de abrir o arquivo, muito menos mmap it.

Verifique as permissões de /dev/mem no seu sistema para se certificar de que estão seguras!

    
por 14.11.2014 / 16:13
2

Os endereços visíveis para um processo de usuário (seja um usuário root ou não-privilegiado) são endereços virtuais, que são mapeados para endereços físicos pela MMU através das tabelas de páginas. Configurar as tabelas de páginas é uma operação privilegiada e só pode ser executada pelo código do kernel; no entanto, assim que as tabelas de páginas forem definidas, o acesso à memória será permitido no modo de usuário.

Concretamente, seu código usa mmap para solicitar que o kernel configure as tabelas de páginas para permitir 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áginas para permitir que ele acesse a memória física.

    
por 28.02.2016 / 22:25
0

O valor de leds é um endereço virtual. Contanto que esteja no espaço de usuário do processo atual, o processo pode acessá-lo diretamente através de instruções como leds[0] = val sem precisar estar no modo privilegiado, não importando onde na RAM esse endereço virtual esteja mapeado para

    
por 26.02.2016 / 05:05