2012-06-21 74 views
7

我想让堆内存只读。为此,我尝试了memalign()mprotect()。但是从memalignment我能得到什么,memalign分配内存远离进程堆。如何保护linux中的堆内存?

我想让堆的一部分为只读。对此有何帮助?

malloc()->mmap()->mprotect()malloc()->mmap()->mprotect()一个假设的想法,但不知道如果这可以帮助...任何示例代码以上实现?

我需要保护堆内的内存地址。与malloc()我得到地址0x10012008左右,而与mmap()它是0xf7ec9000.My的意图是让堆只能读取的一部分只能捕捉任何可能试图通过该堆的trampler。

回答

4

是的,mmap和mprotect是正确的功能。我不明白你当前的接受程度有什么问题,也就是说,你的意思是“我已经用mprotect()尝试过memalign()。但是从memalign中我可以得到什么,memalign从进程堆中分配内存“。

下面是一个例子如何创建一个写保护的存储区:

#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

我可以建议使用'MAP_ANONYMOUS'并避免整个'fopen()'e.t.c.怪事? – thkala

+4

Minor nitpick:'printf'不是[异步安全](https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+信号+处理程序) – Flexo

2

您应该直接使用mmap()malloc()完全。而且,根据您的需要,你可能不需要mprotect()都:

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

在最近的内核和libc的实现中,这将分配的内存请求的金额与指定的保护模式 - 在这种情况下,分配的内存区域可只能读,但不能写。如果你只需要一堆零页,那就行了。否则,生成的区域将被正确对齐,并且您可以使用mprotect()以受控方式在短时间内解除它的保护...