2012-06-21 9 views
7

Chcę zrobić chunck z pamięci sterty tylko do odczytu. Do tego próbowałem z memalign() z mprotect(). Ale z memalignment, co mogę dostać, memalign przydziela pamięć z dala od sterty procesu.Jak mogę chronić pamięć sterty w systemie Linux?

Chcę, aby część sterty była tylko do odczytu. Jakaś pomoc w tej sprawie?

malloc()->mmap()->mprotect() hipotetyczna myśl, ale nie wiesz, czy to może pomóc ... Jakiś przykładowy kod do wdrożenia powyżej?

Potrzebuję chronić adres pamięci w stercie. z malloc() otrzymuję adres około 0x10012008, natomiast przy mmap() jest to 0xf7ec9000. Moim zamiarem jest uczynienie fragmentu heap-meory tylko do odczytu, aby złapać dowolny tramper, który mógłby spróbować uruchomić przez tę stertę.

Odpowiedz

4

Tak, mmap i mprotect są właściwymi funkcjami. Nie rozumiem, jaki jest problem z twoim bieżącym approch, czyli co masz na myśli przez "Dla tego, że próbowałem z memalign() z mprotect(), ale z memalignment, co mogę dostać, memalign przydziela pamięć z dala od sterty procesu . "

Poniżej jest przykład jak stworzyć obszar pamięci chronionej przed zapisem:

#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

Mogę zasugerować użycie 'MAP_ANONYMOUS' i unikanie całego' fopen() 'e.t.c. niesamowitość? – thkala

+4

Drobna nitpick: 'printf' nie jest [Asynchroniczne bezpieczne] (https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+ signal + handlers) – Flexo

2

Należy użyć mmap() bezpośrednio i upuść malloc() całkowicie. Oraz, w zależności od potrzeb, może nie trzeba mprotect() w ogóle:

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

W ostatnich jądrach i libc implementacji tego przydzieli żądaną ilość pamięci z określonym trybie ochrony - w tym przypadku przydzielony obszar pamięci może tylko czytać, ale nie pisać. Jeśli potrzebujesz tylko garstki zero stron, to by to zrobiło. W przeciwnym razie wynikowy obszar zostanie odpowiednio wyrównany i możesz użyć mprotect(), aby wyłączyć ochronę przez krótki czas w kontrolowany sposób ...

Powiązane problemy