7

我想让一大堆堆内存只读。为此,我已经尝试过memalign()使用mprotect()。但是从 memalignment 我能得到什么,memalign 将内存分配到进程堆之外。

我想将堆的某些部分设为只读。有什么帮助吗?

malloc()->mmap()->mprotect()一个假设的想法,但不确定这是否有帮助......上面有任何示例代码吗?

我需要保护堆内的内存地址。使用 malloc() 我得到大约 0x10012008 的地址,而使用 mmap() 它是 0xf7ec9000。我的目的是使堆内存的一部分只读以捕获任何可能试图穿过该堆的践踏者。

4

2 回答 2

4

是的,mmap 和 mprotect 是正确的功能。我不明白你当前的方法有什么问题,即,你的意思是“为此我已经尝试使用 memalign() 和 mprotect()。但是从 memalignment 我能得到什么,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;
}
于 2012-06-21T17:06:45.717 回答
2

您应该mmap()直接使用并完全丢弃malloc()。而且,根据您的需要,您可能根本不需要mprotect()

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

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

于 2012-06-21T17:16:17.533 回答