如何分配具有执行权限的内存?

时间:2010-07-27 09:45:17

标签: c++ c

我想分配一个具有执行权限的内存。 所以我使用mprotect来更改权限。为了获得页面对齐的内存,我使用valloc函数。

void * temp = (void *) valloc(x);

然后

if( mprotect(temp, BLOCK_SIZE, (PROT_READ | PROT_WRITE |PROT_EXEC))) {
   exit(-1);
}

现在我想为这个分配的块添加更多内存。因此我使用realloc函数。

void * new_temp = (void *) realloc(temp, 1024);

这个重新分配会自动将分配的内存的权限更改为我之前设置的内存吗?如果realloc将整个块移动到另一个位置,那么先前分配的内存的权限和新分配的内存是什么?

应该再次使用mprotect来获取执行权限内存。页面大小边界上有realloc的API,例如valloc。 ?

2 个答案:

答案 0 :(得分:4)

尝试使用另一个valloc分配新区域,并复制旧内容。更好的是,停止使用已弃用的valloc,并将其替换为posix_memalign次调用,或直接mmap进行非常大的分配。使用mremap,您可以有效地realloc页面对齐的内存区域。

答案 1 :(得分:1)

  

应该再次使用mprotect来获取执行权限内存。

虚拟内存按页面组织。 mprotect()更改给定虚拟内存块中所有页面上的标志。它独立于实际的内存分配。 IOW,你必须在realloc之后再次调用mprotect()来重新应用权限。而且你必须再次为整个区域调用它,因为realloc()可以代替将现有的块返回指针扩展为新的。

现在考虑一下,我想可能需要在mprotect()之前调用realloc()来删除旧内存区域的exec权限。 malloc() / realloc()是用于管理应用程序虚拟内存中内存的libc函数,而mprotect()是一个独立于应用程序虚拟内存本身运行的系统调用。

  

是否有一个API来重新分配页面大小边界,如valloc。 ?

非常怀疑。

在内存分配密集型应用程序中,realloc()很少能够扩展现有块,并且通常最终会分配新的块+ memcpy()+空闲块。如果realloc()之前的表现是可以接受的,那么它的手工编码版本(考虑更严格的对齐)也应该没问题。

BTW,POSIXv6有一个名为posix_memalign()的新功能。 valloc's man page是一个有趣的读物,主要是为什么不应该首先使用valloc()。

P.S。此外,您始终可以使用标准POSIX函数来查找页面大小sysconf(_SC_PAGESIZE);并自行对齐内存缓冲区。显然,您必须分配new_size+(sysconf(_SC_PAGESIZE)-1)个字节才能有足够的内存来重新对齐指针。