1

malloc我通过and分配了一些大块的内存aligned_alloc,然后我在内存中的一个区域设置了一个栅栏,其大小为一页大小,使用mprotect

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

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

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

还是我应该这样做free?我读到glibc有时会重用一些以前分配的内存,所以如果这个内存区域稍后返回malloc,访问它会导致问题(因为它是PROT_NONE)?

4

2 回答 2

1

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

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

于 2017-04-30T08:27:41.397 回答
1

在@doron 的回答之上,我挖掘了更多,因为我专门在 Linux 上工作。根据posix标准mprotect

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

Linux上,它有点不同:

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

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

其实这正是我遇到的问题,当程序运行一段时间后,它随机崩溃malloc,那是因为malloc正在将它的家政数据写入之前分配的内存中,并且该内存是PROT_NONE由一个更早的mprotect,在我设置之后设置的调用前可写的内存free,程序再也不会崩溃。

话虽这么说,这只是在Linux上,要编写可移植程序,应该mprotect只在mmap'ed内存上使用。

于 2017-05-06T08:27:42.453 回答