2012-06-21 22 views
7

Voglio fare un chunck di memoria heap in sola lettura. Per quello che ho provato con memalign() con mprotect(). Ma dal punto di vista della memoria cosa posso ottenere, memalign alloca la memoria dall'heap del processo.come posso proteggere una memoria heap in linux?

Desidero rendere una parte dell'heap di sola lettura. Qualche aiuto su questo?

malloc()->mmap()->mprotect() un pensiero ipotetico, ma non è sicuro se ciò può aiutare ... Qualsiasi codice di esempio da implementare sopra?

Ho bisogno di proteggere l'indirizzo di memoria all'interno dell'heap. con malloc() ottengo l'indirizzo intorno a 0x10012008 mentre con mmap() è 0xf7ec9000. La mia intenzione è di rendere una parte di heap-meory da leggere solo per catturare qualsiasi trampler che potrebbe tentare di eseguire quell'heap.

risposta

4

Sì, mmap e mprotect sono le funzioni corrette. Non capisco qual è il problema con il tuo attuale approc, cioè, cosa intendi con "Per quello ho provato con memalign() con mprotect(). Ma dal memalignment cosa posso ottenere, memalign alloca la memoria dall'heap del processo ".

Di seguito è riportato un esempio come creare un area di memoria protetta da scrittura:

#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

Posso suggerire di utilizzare 'MAP_ANONYMOUS' ed evitare l'intero' fopen() 'e.t.c. stranezza? – thkala

+4

Minor nitpick: 'printf' non è [Async safe] (https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+ segnale + gestori) – Flexo

2

Si dovrebbe usare mmap() direttamente e rilasciare malloc() del tutto. E, a seconda delle esigenze, potrebbe non essere necessario mprotect() affatto:

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

Il kernel recenti e le implementazioni libc questo sarà allocare la quantità di memoria richiesta con la modalità di protezione specificato - in questo caso l'area di memoria allocata può solo essere letto, ma non scritto Se hai bisogno solo di un mucchio di pagine zero, questo dovrebbe essere. In caso contrario, l'area risultante verrà allineata correttamente e sarà possibile utilizzare mprotect() per annullare la protezione per brevi periodi di tempo in modo controllato ...

Problemi correlati