fluter
fluter

Reputation: 13816

Do I need to reset protection before calling free

I allocated some large chunks of memory through malloc and aligned_alloc, and then I setup a fence to a region inside the memory with size of one page size, using mprotect:

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

Now I'm done with the memory and is calling free(buf); to release it, my questions is do I need to reset mprotect before calling free, like this:

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

Or should I just do free? I read that glibc will sometimes reuse some of the previously allocated memory, so if this region of memory is returned to later malloc, will accessing it cause problems(since it's PROT_NONE)?

Upvotes: 1

Views: 913

Answers (2)

doron
doron

Reputation: 28902

Malloc allocated from the heap does not necessarily request the memory from the system. Likewise free does not necessarily return the memory to the system.

For what you are doing you should use mmap munmap which always goes to the system. If you use mfree there is no need to call mprotect beforehand.

Upvotes: 1

fluter
fluter

Reputation: 13816

On top of @doron 's answer, I digged a little more because I was specifically working on Linux. According posix standard of mprotect:

The behavior of this function is unspecified if the mapping was not established by a call to mmap().

While on Linux, it is a bit different:

On Linux it is always permissible to call mprotect() on any address in a process's address space (except for the kernel vsyscall area). In particular it can be used to change existing code mappings to be writable.

That means it is indeed allowed to call mprotect on malloc'ed memory regions, but free will not reset it as there is no way to know the old protection flags, so I have to reset the flags before calling free.

In fact, this is exactly the problem I met, when the program runs for a while, it randomly crashes in malloc, that is because malloc is writing it's housekeeping data into the previously allocated memory and that memory was set to PROT_NONE by an earlier mprotect, after I set the memory to writable before calling free, the program never crash again.

That's being said, this is only on Linux, to write portable program, one should use mprotect only on mmap'ed memory.

Upvotes: 1

Related Questions