¿Cómo funciona mmap ' ing / dev / mem a pesar de estar en modo sin privilegios?
On febrero 9, 2021 by adminHasta donde yo entiendo, los programas de espacio de usuario se ejecutan en el modo sin privilegios y, por lo tanto, no tienen acceso directo a la memoria o E / S.
Entonces, ¿exactamente cómo podemos acceder directamente a la memoria o 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 comúnmente utilizado en dispositivos integrados.
Ahora la variable leds
se puede usar sobre la marcha para acceder cualquier dispositivo que pudiera estar presente en 0x80840000.
Ya no utilizaremos ninguna llamada al sistema para acceder a esa dirección.
Incluso algo como
leds[0x20] = val;
funcionaría.
Pero las operaciones privilegiadas, como leer / escribir directamente a / desde una dirección de E / S deberían ser posibles solo poniendo el procesador en modo privilegiado a través de una llamada al sistema.
Fuente .
Comentarios
Responder
Permitir el acceso a /dev/mem
por procesos sin privilegios sería un problema de seguridad y no debería permitirse.
En mi sistema, ls -l /dev/mem
se ve así:
crw-r----- 1 root kmem 1, 1 Sep 8 10:12 /dev/mem
Entonces root
pueden leerlo y escribirlo, miembros de la kmem
group (del cual no hay ninguno) puede leerlo pero no escribirlo, y todos los demás no pueden abrirlo en absoluto. Así que esto debería ser seguro.
Si su /dev/mem
es algo como el mío, su proceso sin privilegios ni siquiera debería haber podido abrir el archivo, y mucho menos mmap
it.
Verifique los permisos de /dev/mem
en su sistema para asegurarse de que estén seguros.
Comentarios
- Pero suponiendo que estoy haciendo esto como root … ¿Significa que un proceso ejecutado por root obtiene el kernel privilegios de acceso de nivel?
- Bueno, si ' estás haciendo esto como root, entonces tienes acceso a todo. ' no estoy seguro de lo que quieres decir con " privilegios de acceso a nivel de kernel ", pero root ciertamente puede hacer lo que quiera, de una forma u otra (en particular, por ejemplo, creando y cargando dinámicamente un nuevo módulo del kernel).
- Sí, eso ' s correcto: cuando mapea un archivo, luego puede leer & escribir el archivo sin el uso de ninguna llamada al sistema. Eso ' es cierto si ' ha mapeado un archivo de disco normal o un dispositivo especial como
/dev/mem
. Si lo prefiere, puede abrir/dev/mem
y emitirread()
ywrite()
llamadas al sistema. Entonces no estaría enviando E / S sin el uso de llamadas al sistema. El resultado final es el mismo, pero si tiene muchas E / S pequeñas que hacer,mmap()
y el acceso directo probablemente funcionarán mejor específicamente porque no ' ¡No necesita llamadas al sistema! ¡Esto también es cierto para los archivos normales! - @ Stark07 Creo que ' no entendiste el punto. Los
mmap
(y/dev/mem
) en sí mismos NO proporcionan acceso directo al memoria del sistema, y es imposible hacerlo en Ring 4. Lo que hace en cambio es simplemente mapear un archivo (o recurso) a una dirección virtual específica en el proceso de llamada, al igual que sucede cuando se carga un programa /exec
ed (en este caso, la imagen del programa esmmap
ed en la memoria virtual). - TL; DR Un proceso sin privilegios no tiene acceso directo a los recursos del sistema, pero puede hacerlo cuando esos recursos están asignados a su espacio de direcciones virtuales . No hay ' diferencia entre acceder a su pila / montón / rodata / lo que sea y acceder a la memoria del kernel. Eventualmente ambos acceden a la memoria física real, mientras que el último caso simplemente se encuentra bajo el programa ' s control.
Respuesta
Las direcciones visibles a un proceso de usuario (ya sea que se ejecute como root o un 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 solo puede realizarse mediante el código del núcleo; sin embargo, una vez que las tablas de la página están configuradas, el acceso a la memoria está permitido en modo de usuario.
Concretamente, su código usa mmap
para solicitar que el núcleo configure el 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 a /dev/mem
) y configura las tablas de páginas para permitirle acceder a la memoria física.
Respuesta
El valor de leds
es una dirección virtual. Siempre que esté en el espacio de usuario del proceso actual, el proceso puede acceder a él directamente a través de instrucciones como leds[0] = val
sin tener que estar en modo privilegiado, sin importar en qué parte de la RAM esté asignada esta dirección virtual
*
en la declaración deleds
, pero ese ' es solo código, no hay evidencia de que esto funcione realmente como un usuario sin privilegios; en mi experiencia (limitada), todo se ejecuta como root en dispositivos integrados.root
tiene muchos privilegios, que incluyen la posibilidad de anular los permisos del sistema de archivos. Algunos " archivos " son en realidad acceso a dispositivos (como disco o memoria), que están prohibidos para los usuarios habituales. Noroot
. Peroroot
se ejecuta en el espacio de usuario , por lo que no ' no disfruta de todos los privilegios del modo de sistema. (ejecutar instrucciones privilegiadas, principalmente).