c linux system-calls mprotect virtualquery

¿Hay una mejor manera de analizar/proc/self/maps para descubrir la protección de la memoria?



linux system-calls (2)

En Linux (o Solaris) hay una manera mejor que la de analizar a mano /proc/self/maps varias veces para averiguar si puede o no leer, escribir o ejecutar lo que está almacenado en una o más direcciones en la memoria.

Por ejemplo, en Windows tienes VirtualQuery .

En Linux, puedo mprotect para cambiar esos valores, pero no puedo leerlos.

Además, ¿hay alguna manera de saber cuándo cambian esos permisos (por ejemplo, cuando alguien usa mmap en un archivo a mis espaldas) que hacer algo terriblemente invasivo y usar ptrace en todos los hilos en el proceso e interceptar cualquier intento de hacer un syscall que podría afectar el mapa de memoria?

Actualizar:

Desafortunadamente, estoy usando esto dentro de un JIT que tiene muy poca información sobre el código que está ejecutando para obtener una aproximación de lo que es constante. Sí, me doy cuenta de que podría tener un mapa constante de datos mutables, como la página vsyscall utilizada por Linux. Puedo recurrir a la suposición de que todo lo que no está incluido en el análisis inicial es mutable y peligroso, pero no estoy del todo contento con esa opción.

En este momento, lo que hago es leer /proc/self/maps y construir una estructura en la que puedo realizar búsquedas binarias para la protección de una dirección determinada. Cada vez que necesito saber algo acerca de una página que no está en mi estructura, vuelvo a leer / proc / self / maps suponiendo que se haya agregado mientras tanto o de todos modos estaría a punto de fallar.

Simplemente parece que analizar el texto para obtener esta información y no saber cuándo cambia es tremendamente difícil. ( /dev/inotify no funciona en prácticamente nada en /proc )


No conozco un equivalente de VirtualQuery en Linux. Pero hay otras formas de hacerlo que pueden funcionar o no:

  • configura un manejador de señal que atrapa SIGBUS / SIGSEGV y continúa con su lectura o escritura. Si la memoria está protegida, se invocará el código de captura de señal. Si no es así, no se llama al código de interceptación de señal. De cualquier manera que ganes.

  • podría realizar un seguimiento cada vez que llame a mprotect y crear una estructura de datos correspondiente que le ayude a saber si una región está protegida contra lectura o escritura. Esto es bueno si tiene acceso a todo el código que usa mprotect .

  • puede supervisar todas las llamadas mprotect en su proceso al vincular su código con una biblioteca que redefine la función mprotect . A continuación, puede crear la estructura de datos necesaria para saber si una región está protegida contra lectura o escritura y luego llamar al sistema mprotect para establecer realmente la protección.

  • puede intentar usar /dev/inotify y monitorear el archivo /proc/self/maps para cualquier cambio. Supongo que este no funciona, pero debería valer la pena intentarlo.


Hay sorta is / was / proc / [pid | self] / pagemap, documentación en el kernel, advertencias aquí: https://lkml.org/lkml/2015/7/14/477 Así que no es completamente inofensivo ... .