保护已分配的内存

3

我需要动态分配一些内存,每个内存块都有一定的保护 - 随时可读写或只读。

我尝试使用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

1
你得到了什么“errno”错误代码?如果返回-1,则“errno”将相应地设置。这里是该命令的 man 手册页面。 - gongzhitaao
@gongzhitaao 22:EINVAL - Ari
1
根据man页面,EINVAL的意思是“addr不是有效指针,或者不是系统页面大小的倍数”。malloc不能保证对齐,你应该使用类似于posix_memalign的东西。 - Oliver Charlesworth
将malloc分配的内存标记为只读,也会将同一页上的所有其他内存位都标记为只读,这很可能会混淆您的程序和运行时,当它们尝试写入它们合法地malloc的内存时,可能会出现堆分配。 - SecurityMatt
2个回答

5

这里最后一部分很重要。malloc可能不会给你一个页面对齐的内存,即使你请求了一个页面的大小,所以你要么分配一个合适大小并且对齐的内存块,或者使用例如posix_memalign()来分配页面对齐的内存。

如果mprotect()失败,你也应该检查errno以了解更多信息。


关于memalign:建议新代码不要使用此函数,并且建议重新考虑在旧代码中使用它。它仅包含在内,以允许旧代码重新编译。UNIX 98规范没有此功能。大多数现代操作系统的内存分配例程返回对齐的内存。 - Ari
@Ari 在这方面,最后一部分并不相关,虽然内存分配例程返回对齐的内存,但它们不会返回页面对齐的内存。无论如何,我已将其更改为现代变体posix_memalign。 - nos

5
如果您想分配一段内存页面,正确的选择可能是使用 mmap()
void *x = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);

请注意,由于您在调用中传递了权限,因此您实际上不需要在之后使用mprotect()。当然,您可以稍后使用它来更改权限,例如如果您想在将某些数据加载到页面之前将其设置为只读。您可以使用munmap()来释放它。
由于这是一个匿名映射,因此不使用后备文件,因此在这个意义上它的行为很像malloc()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接