【问题标题】:How to allocate a memory with execute permissions?如何分配具有执行权限的内存?
【发布时间】:2010-07-27 09:45:17
【问题描述】:

我想分配一个具有执行权限的内存。 所以我使用 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。 ?

【问题讨论】:

  • 你应该用适当的操作系统标记它,因为这更像是一个操作系统而不是语言问题。
  • valloc() 是在 SUSv3 中删除的遗留 BSD 函数。假设一些 POSIX 操作系统,如 Linux 或 BSD。
  • @David:不是真的,Windoze 和 Linux 都支持这个东西(其他操作系统不存在),API 只是在 POSIX 没有标准化的地方有所不同。

标签: c++ c


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    是否有像 valloc 一样在页面大小边界上重新分配的 API。 ?

    非常怀疑。

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

    顺便说一句,POSIXv6 有一个名为posix_memalign() 的新函数。 valloc's man page 读起来很有趣,主要是为什么不应该首先使用 valloc()。

    附:您也可以随时使用标准 POSIX 函数来查找页面大小 sysconf(_SC_PAGESIZE); 并自己对齐内存缓冲区。显然,您必须分配 new_size+(sysconf(_SC_PAGESIZE)-1) 字节才能有足够的内存来重新对齐指针。

    【讨论】:

    • 您绝对不想仅仅因为该页面中的 one 缓冲区不再需要它而删除该页面的 EXEC 权限。除非您只有一个动态分配的可执行缓冲区,否则您知道同一页面中没有另一个可执行缓冲区。
    猜你喜欢
    • 2012-10-20
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 2017-04-17
    相关资源
    最近更新 更多