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

3 minutos de lectura

avatar de usuario
edward kmett

En Linux (o Solaris), ¿hay una mejor manera que el análisis manual? /proc/self/maps repetidamente 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 volver a leerlos.

Además, ¿hay alguna forma de saber cuándo cambian esos permisos (por ejemplo, cuando alguien usa mmap en un archivo a mis espaldas) además de hacer algo terriblemente invasivo y usar ptrace en todos los subprocesos del proceso e interceptando cualquier intento de realizar una 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. I lata recurrir con seguridad 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 satisfecho con esa opción.

Ahorita lo que hago es leer /proc/self/maps y construir una estructura en la que pueda realizar búsquedas binarias para la protección de una dirección dada. Cada vez que necesito saber algo sobre 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 en el segmento de todos modos.

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

No conozco 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 usted gana.

  • podrías rastrear cada vez que llamas mprotect y construya una estructura de datos correspondiente que lo 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 utiliza mprotect.

  • Puedes monitorear todos los mprotect llamadas 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 establecer realmente la protección.

  • puedes 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.

  • Cuando recibo un SIGSEGV es demasiado tarde. Necesito saber si algunos datos son constantes para saber que puedo doblarlos constantemente de forma “segura”. Con los trucos apropiados para datos no constantes de mmap’ed constantes y la página vsyscall.

    –Edward Kmett

    6 de noviembre de 2008 a las 18:45

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

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad