Entonces, estoy tratando de verificar si puedo cambiar correctamente los derechos de acceso en la memoria asignada asignada usando mprotect y esto es lo que escribí:
#include <stdio.h> #include <sys/mman.h> #include <malloc.h> #include <unistd.h> void main() { int pagesize; pagesize = getpagesize(); void *p; p = malloc(pagesize); getchar(); int q = posix_memalign(&p, pagesize, pagesize); getchar(); int a = mprotect(p, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC); getchar(); free(p); } Ahora, después de cada función, estoy usando getchar para analizar mi segmento de memoria usando el archivo cat /proc/<pid>/maps y esto es lo que obtengo: (solo muestra la información sobre el montón, ya que esa es mi única preocupación) Después de posix_memalign :
01776000-01798000 rw-p 00000000 00:00 0 [heap] Después de la función mprotect :
01776000-01778000 rw-p 00000000 00:00 0 [heap] 01778000-01779000 rwxp 00000000 00:00 0 [heap] 01779000-01798000 rw-p 00000000 00:00 0 [heap] Entonces, si nota que el montón asignado antes se divide en tres partes después de usar mprotect y solo la segunda parte del montón obtiene los permisos de acceso que otorgué en la función. ¿Por qué ocurre esta división y por qué solo la segunda región del montón dividido obtiene los permisos? Nota: He buscado en las páginas de manual y no he encontrado absolutamente nada al respecto.
0x1000 bytes en la dirección p , que es 0x1778000 en su ejemplo. Cuando llamó a mprotect con estos parámetros, funcionó como quería y marcó 01778000-01779000 rwxp .
Por lo tanto, su pregunta podría formularse más acertadamente como, ¿por qué posix_memalign(3) parece asignar más espacio del que solicitó?
Echemos un vistazo a man posix_memalign :
POSIX requiere que la memoria obtenida de posix_memalign() se pueda liberar usando free(3).
Pero, ¿cómo sabe free(3) cuántos bytes liberar? Debe almacenarlo en algún lugar fuera de la página que asignó. ¿Y cómo saben las invocaciones posteriores de malloc(3) o amigos dónde encontrar bloques liberados? Estos también deben almacenarse en algún lugar.
Y no sorprende que el asignador de almacenamiento dinámico almacene las estructuras de datos que utiliza para administrar el almacenamiento dinámico en el almacenamiento dinámico.
Si desea una forma de más bajo nivel para asignar una página, use mmap(2) :
p = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); Usted administra esta memoria, cuando llama a munmap(2) , el mapeo se elimina notificando al núcleo directamente. Sin reciclaje ni gestión realizada en el espacio del usuario.
Más información sobre lo que hace malloc(3) : ¿Cómo funcionan malloc() y free()?
Artículo de Wikipedia sobre las instalaciones de memoria dinámica de C: https://en.wikipedia.org/wiki/C_dynamic_memory_allocation
Implementación de glibc de malloc(3) et al: https://github.com/lattera/glibc/blob/master/malloc/malloc.c#L3016
Publicación de blog sobre la implementación de glibc: https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/