2012-06-21 17 views
7

Quiero hacer un montón de memoria de montón de solo lectura. Para eso he intentado con memalign() con mprotect(). Pero de la correspondencia que puedo obtener, memalign asigna memoria lejos del montón de proceso.¿cómo puedo proteger una memoria de montón en Linux?

Quiero hacer que una parte del montón sea de solo lectura. ¿Alguna ayuda sobre eso?

malloc()->mmap()->mprotect() un pensamiento hipotético, pero no estoy seguro si eso puede ayudar ... ¿Algun código de muestra para implementar arriba?

Necesito proteger la dirección de memoria dentro del montón. con malloc() obtengo una dirección alrededor de 0x10012008 mientras que con mmap() es 0xf7ec9000. Mi intención es hacer que una parte de heap-meory sea de solo lectura para atrapar cualquier trampler que pueda intentar correr a través de ese montón.

Respuesta

4

Sí, mmap y mprotect son las funciones correctas. No entiendo cuál es el problema con tu aproximación actual, es decir, a qué te refieres con "Por eso he intentado con memalign() con mprotect(). Pero a partir de la correspondencia que puedo obtener, memalign asigna memoria lejos del montón de procesos "

A continuación se muestra un ejemplo de cómo crear un área de memoria protegida contra escritura:

#include <fcntl.h> 
#include <signal.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/mman.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 

static int alloc_size; 
static char* memory; 

void segv_handler (int signal_number) { 
printf ("memory accessed!\n"); 
mprotect (memory, alloc_size, PROT_READ | PROT_WRITE); 
} 

int main() { 
int fd; 
struct sigaction sa; 

/* Install segv_handler as the handler for SIGSEGV. */ 
memset (&sa, 0, sizeof (sa)); 
    sa.sa_handler = &segv_handler; 
sigaction (SIGSEGV, &sa, NULL); 

/* Allocate one page of memory by mapping /dev/zero. Map the memory 
as write-only, initially. */ 
    alloc_size = getpagesize(); 
fd = open ("/dev/zero", O_RDONLY); 
    memory = mmap (NULL, alloc_size, PROT_WRITE, MAP_PRIVATE, fd, 0); 
    close (fd); 
    /* Write to the page to obtain a private copy. */ 
    memory[0] = 0; 
/* Make the memory unwritable. */ 
    mprotect (memory, alloc_size, PROT_NONE); 

/* Write to the allocated memory region. */ 
memory[0] = 1; 

    /* All done; unmap the memory. */ 
printf ("all done\n"); 
munmap (memory, alloc_size); 
return 0; 
} 
+5

Puedo sugerir usar 'MAP_ANONYMOUS' y evitar todo el' fopen() 'e.t.c. ¿rareza? – thkala

+4

Minit nitpick: 'printf' no es [Seguridad asíncrona] (https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+ señal + controladores) – Flexo

2

Debe utilizar directamente mmap() y soltar malloc() por completo. Y, dependiendo de sus necesidades, puede que no necesite mprotect() en absoluto:

ptr = mmap(NULL, length, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 

En los últimos núcleos e implementaciones libc esto va a destinar el importe solicitado de la memoria con el modo de protección especificada - en este caso el área de memoria asignada puede solo se debe leer, pero no escribir Si solo necesitas un montón de cero páginas, eso sería suficiente. De lo contrario, el área resultante se alineará correctamente y puede usar mprotect() para desprotegerla por períodos cortos de tiempo de manera controlada ...

Cuestiones relacionadas