【问题标题】:Protecting allocated memory保护分配的内存
【发布时间】:2013-03-24 09:36:56
【问题描述】:

我需要动态分配一些内存部分,每个部分都有一些保护 - RW 或 RX。

我尝试通过malloc分配内存,但mprotect总是返回-1 Invalid argument

我的示例代码:

void *x = malloc(getpagesize());
mprotect(x, getpagesize(), PROT_READ); // returns -1, it;s sample, so only R, not RW or RX

【问题讨论】:

  • 你得到的errno 是什么?如果返回 -1,则将相应地设置 errnoHere 是手册页。
  • @gongzhitaao 22: EINVAL
  • 嗯,根据手册页,EINVAL 的意思是“addr 不是一个有效的指针,或者不是系统页面大小的倍数。”。 malloc 不保证对齐,你应该使用类似 posix_memalign 的东西。
  • 将 malloc 的分配标记为 READONLY 也会将同一页面上的所有其他内存位标记为 READONLY,这可能会混淆您的程序位和可能存在堆分配的运行时当他们尝试写入内存时,他们已经合法地 malloc 了

标签: c memory malloc mprotect


【解决方案1】:

如果要分配一页内存,正确的选择大概是使用mmap()

void *x = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);

请注意,由于您将权限传递给调用,因此之后您真的不需要使用mprotect()。但是,您可以稍后使用它来更改权限,例如,如果您想在页面只读之前将一些数据加载到页面中。您可以稍后使用 munmap() 释放它。

因为这是一个匿名地图,所以没有使用任何支持文件,所以它的行为很像 malloc() 在这个意义上。

【讨论】:

    【解决方案2】:

    mprotect() 更改调用进程内存的保护 包含间隔中地址范围的任何部分的页面 [地址,地址+len-1]。地址 必须与页面边界对齐

    这里的最后一部分很重要。 malloc 可能不会仅仅因为您请求页面的大小而给您页面对齐的内存,因此您要么必须分配合适的内存块并对齐它,要么使用例如分配页面对齐的内存posix_memalign()

    如果 mprotect() 失败,您还应该检查 errno,以了解有关失败原因的更多信息。

    【讨论】:

    • 关于memalign:It is recommended that new code not use this function and it is further recommended that its use in older code be reconsidered. It is only included to allow older code to recompile. The UNIX 98 specification does not have this function. Most modern operating systems memory allocation routines return aligned memory.
    • @Ari 最后一部分与这方面无关,虽然内存分配例程返回对齐的内存,但它们不返回页面对齐的内存。不管怎样,我把它改成了现代版本,posix_memalign
    猜你喜欢
    • 2011-09-13
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多