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

StackOverflow https://stackoverflow.com/questions/269314

Pregunta

En Linux (o Solaris), existe una mejor manera que analizar manualmente / proc / self / maps repetidamente para determinar si puede leer, escribir o ejecutar lo que esté almacenado en uno o más direcciones en la memoria?

Por ejemplo, en Windows tiene VirtualQuery .

En Linux, puedo mprotect para cambiar esos valores, pero no puedo volver a 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 no sea hacer algo terriblemente invasivo y usar ptrace en todos los hilos del proceso e interceptando cualquier intento de hacer una syscall que pueda afectar el mapa de memoria?

Update:

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 retroceder de forma segura suponiendo 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 pueda buscar binariamente 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 asumiendo que se ha agregado mientras tanto o estaría a punto de fallar de todos modos.

Simplemente parece que analizar el texto para obtener esta información y no saber cuándo cambia es terriblemente descuidado. ( / dev / inotify no funciona en casi nada en / proc )

¿Fue útil?

Solución

No sé un equivalente de VirtualQuery en Linux. Pero algunas otras formas de hacerlo que pueden o no funcionar son:

  • configura un controlador de señal que atrapa SIGBUS / SIGSEGV y continúa con su lectura o escritura. Si la memoria está protegida, se llamará a su código de captura de señal. Si no, su código de captura de señal no se llama. De cualquier manera ganas.

  • puede rastrear cada vez que llama a mprotect y crea una estructura de datos correspondiente que le ayuda 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 monitorear todas las llamadas mprotect en su proceso al vincular su código con una biblioteca que redefine la función mprotect . Luego puede construir la estructura de datos necesaria para saber si una región está protegida contra lectura o escritura y luego llamar al sistema mprotect para configurar 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 vale la pena intentarlo.

Otros consejos

Hay algo de / was / proc / [pid | self] / pagemap, documentación en el kernel, advertencias aquí: https://lkml.org/lkml/2015/7/14/477 Por lo tanto, no es completamente inofensivo ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top