Como funciona o mmap'ing /dev/mem apesar de estar no modo sem privilégios?

Como funciona o mmap'ing /dev/mem apesar de estar no modo sem privilégios?

Pelo 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 locais de E/S quando mapeamos /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 embarcados.

Agora a variável ledspode ser usada dinamicamente 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;

podia funcionar.

Mas operações privilegiadas, como ler/escrever diretamente de/para um endereço de E/S, só devem ser possíveis colocando o processador em modo privilegiado por meio de uma chamada de sistema.

Fonte.

Responder1

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

No meu sistema, ls -l /dev/memfica assim:

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

Assim, rootpode ler e escrever, os membros do kmemgrupo (dos quais não há nenhum) podem lê-lo, mas não podem escrevê-lo, e todos os outros não podem abri-lo. Portanto, isso deve ser seguro.

Se o seu /dev/memfor parecido com o meu, seu processo sem privilégios nem deveria ter sido capaz de abrir o arquivo, muito menos mmapele.

Verifique as permissões do /dev/memseu sistema para ter certeza de que estão seguras!

Responder2

Os endereços visíveis para um processo de usuário (seja executado como root ou como usuário sem privilégios) são endereços virtuais, que são mapeados para endereços físicos pelo MMU por meio das tabelas de páginas. Configurar as tabelas de páginas é uma operação privilegiada e só pode ser realizada pelo código do kernel; entretanto, uma vez definidas as tabelas de páginas, o acesso à memória é permitido no modo de usuário.

Concretamente, seu código mmapsolicita que o kernel configure as 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 /dev/mem) e configura as tabelas de páginas para permitir que ele acesse a memória física.

Responder3

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, leds[0] = valsem precisar estar em modo privilegiado, não importa onde na RAM esse endereço virtual esteja mapeado.

informação relacionada