Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allocate a memory with execute permissions?

Tags:

c++

c

I want to allocate a memory with execute permissions. So I use mprotect to change the permissions.. To get a page aligned memory I use a valloc function.

void * temp = (void *) valloc(x);

and then

if( mprotect(temp, BLOCK_SIZE, (PROT_READ | PROT_WRITE |PROT_EXEC))) {
   exit(-1);
}

Now I want to add more memory to this allocated block. Hence I use a realloc function.

void * new_temp = (void *) realloc(temp, 1024);

Will this reallocate automatically change the permissions of the allocated memory to the ones I had set earlier ?? In case realloc moves the entire block to a different location, what be the permissions of allocated memory earlier and the newly allocated memory?

Should mprotect be used again to get execute permissions memory. And is there a API to realloc on page size boundary like valloc. ?

like image 555
user403219 Avatar asked Jul 27 '10 09:07

user403219


2 Answers

Should mprotect be used again to get execute permissions memory.

Virtual memory is organized in pages. mprotect() changes the flags on all pages in the given block of virtual memory. It is independent from the actual memory allocation. IOW, you have to call mprotect() again after realloc to reapply the permissions. And you have to call it again for the whole region, since realloc() can instead of extending the existing block return pointer to a new one.

Thinking about it now, I think one might need to call mprotect() before the realloc() to remove the exec permissions from the old memory region. malloc()/realloc() are libc functions for management of memory inside the application's virtual memory, while mprotect() is a syscall operating independently on the application's virtual memory itself.

And is there a API to realloc on page size boundary like valloc. ?

Very much doubt it.

In memory allocation intensive application, realloc() is rarely capable of extending the existing block and often ends up allocating new block + memcpy() + free old block. If realloc() performance was acceptable before, than its hand-coded version (taking stricter alignment into account) should be fine too.

BTW, POSIXv6 has a new function called posix_memalign(). valloc's man page is an interesting read, mostly why one shouldn't use the valloc() in the first place.

P.S. Also you can always use standard POSIX function to find the page size sysconf(_SC_PAGESIZE); and align memory buffer yourself. Obviously you have to allocate new_size+(sysconf(_SC_PAGESIZE)-1) bytes to have sufficient memory to realign the pointer.

like image 28
Dummy00001 Avatar answered Nov 12 '22 05:11

Dummy00001


Try allocating a new region with another valloc, and copying the old contents across. Better yet, stop using the deprecated valloc, and replace it with either posix_memalign calls, or directly mmap for very large allocations. Using mremap you could effectively realloc page-aligned memory regions.

like image 105
Matt Joiner Avatar answered Nov 12 '22 05:11

Matt Joiner