¿Cómo funciona mmap'ing /dev/mem a pesar de estar en modo sin privilegios?

¿Cómo funciona mmap'ing /dev/mem a pesar de estar en modo sin privilegios?

Hasta donde tengo entendido, los programas del espacio de usuario se ejecutan en modo sin privilegios y, por lo tanto, no tienen acceso directo a la memoria ni a la E/S.

Entonces, ¿cómo exactamente podemos acceder directamente a la memoria o a las ubicaciones de E/S cuando mmap /dev/mem en programas de espacio de usuario?

Por ejemplo:

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 es un truco muy utilizado en dispositivos integrados.

Ahora la variable ledsse puede utilizar sobre la marcha para acceder a cualquier dispositivo que pueda estar presente en 0x80840000.

Ya no utilizaremos ninguna llamada al sistema para acceder a esa dirección.

Incluso algo como

leds[0x20] = val;

trabajaría.

Pero las operaciones privilegiadas, como leer/escribir directamente en/desde una dirección de E/S, sólo deberían ser posibles poniendo el procesador en modo privilegiado a través de una llamada al sistema.

Fuente.

Respuesta1

Permitir el acceso a /dev/memprocesos sin privilegios sería de hecho un problema de seguridad y no debería permitirse.

En mi sistema, ls -l /dev/memse ve así:

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

Entonces rootpueden leerlo y escribirlo, los miembros del kmemgrupo (que resulta que no hay ninguno) pueden leerlo pero no escribirlo, y todos los demás no pueden abrirlo en absoluto. Entonces esto debería ser seguro.

Si /dev/memse parece en algo al mío, su proceso sin privilegios ni siquiera debería haber podido abrir el archivo, y mucho menos mmap.

¡Verifique los permisos de /dev/memsu sistema para asegurarse de que sean seguros!

Respuesta2

Las direcciones visibles para un proceso de usuario (ya sea que se ejecute como root o como usuario sin privilegios) son direcciones virtuales, que la MMU asigna a direcciones físicas a través de las tablas de páginas. La configuración de las tablas de páginas es una operación privilegiada y sólo puede realizarse mediante código del kernel; sin embargo, una vez configuradas las tablas de páginas, se permite acceder a la memoria en modo usuario.

Concretamente, su código suele mmapsolicitar que el kernel configure las tablas de páginas para permitir el acceso a un rango determinado de memoria física. El kernel verifica los privilegios del proceso (tiene acceso de lectura/escritura /dev/mem) y configura las tablas de páginas para permitirle acceder a la memoria física.

Respuesta3

El valor de ledses una dirección virtual. Siempre que esté en el espacio de usuario del proceso actual, el proceso puede acceder a él directamente mediante instrucciones, como leds[0] = valsin tener que estar en modo privilegiado, sin importar en qué parte de la RAM esté asignada esta dirección virtual.

información relacionada