在免费拨打电话之前是否需要重置保护

时间:2017-04-30 08:17:39

标签: c linux memory posix mprotect

我通过mallocaligned_alloc分配了一些大块内存,然后使用mprotect设置围栏到内存中大小为一页大小的区域:< / p>

void *buf = malloc(128 * PAGE_SIZE);
int ret = mprotect(buf, PAGE_SIZE, PROT_NONE);

现在我已经完成了内存并且正在调用free(buf);来释放它,我的问题是我需要在调用mprotect之前重置free,如下所示:< / p>

ret = mprotect(buf, PAGE_SIZE, PROT_READ|PROT_WRITE);
free(buf);

或者我应该free?我读过glibc有时会重用一些先前分配的内存,所以如果这个内存区域返回到后来的malloc,访问它会导致问题(因为它PROT_NONE)?< / p>

2 个答案:

答案 0 :(得分:1)

从堆分配的Malloc不一定从系统请求内存。同样,free不一定会将内存返回给系统。

对于你正在做的事情,你应该使用总是进入系统的mmap munmap。如果使用mfree,则无需事先调用mprotect。

答案 1 :(得分:0)

除了@doron的回答,我还挖了一点,因为我专门研究Linux。根据{{​​3}}:

  

如果未通过调用mmap()建立映射,则未指定此函数的行为。

posix standard of mprotect上,它有点不同:

  

在Linux上,始终允许在进程的地址空间中的任何地址上调用mprotect()(内核vsyscall区域除外)。特别是它可以用于将现有代码映射更改为可写。

这意味着确实允许在mprotect个内存区域调用malloc,但free不会重置它,因为无法知道旧的保护标志,所以我必须在调用free之前重置标志。

事实上,这正是我遇到的问题,当程序运行一段时间后,它会在malloc中随机崩溃,这是因为malloc正在将它的内务处理数据写入以前分配的内存中并且在我调用PROT_NONE之前将内存设置为可写之后,内存被先前的mprotect设置为free,程序再也不会崩溃。

有人说,这只是在Linux上编写可移植程序,只应在mprotect'内存上使用mmap