I was wondering if there is a portable way to dynamically allocate memory and then restrict read/write access to a portion of this memory, e. g. using the POSIX function mprotect(). I can think of the following approaches:
- Allocate memory using
mmap(), i. e.mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0): Here, the memory protection flags can already be given in the initial allocation call, and can optionally be modified later usingmprotect().
Problem:MAP_ANONYMOUSis not specified by POSIX, although it’s supposedly supported by “almost all” or “most” systems. - Apparently, using
mmap()on/dev/zerois an alternative toMAP_ANONYMOUS. This would make themmap()call itself fully POSIX-compatible, but it seems that this behavior is not necessarily more portable thanMAP_ANONYMOUS(apparently does not work on Mac OS X/macOS). - Allocate memory using
aligned_alloc()(orposix_memalign()) and usemprotect().
Problem: The behavior ofmprotect()according to POSIX is only specified for memory obtained viammap(), although at least “on Linux, it is always permissible to callmprotect()on any address in a process’s address space (except for the kernel vsyscall area)”.
So from the standards point of view, the problem is that mprotect() is only specified in combination with mmap(), but there is no standard that actually specifies dynamic memory allocation with mmap(). It seems that option (1.) is the most portable. Is there another approach that works on more systems (or, even better, is actually specified by a standard)?
How about shared memory object via
shm_open?shm_openreturns a file descriptor which can be mapped bymmapand thereforemprotect(ed).