POSIX requires that mmap()
zero any memory that it allocates.
It can take a while to initialize the memory, so QNX Neutrino provides a
way to relax the POSIX requirement.
This allows for faster starting, but can be a security problem.
Note:
This feature was added in the QNX Neutrino Core OS 6.3.2.
Avoiding initializing the memory requires the cooperation of the process
doing the unmapping and the one doing the mapping:
- The
munmap_flags()
function is a non-POSIX function that's similar to
munmap()
but lets you control what happens when the memory is next mapped:
int munmap_flags( void *addr, size_t len,
unsigned flags );
If you specify a flags argument of 0, munmap_flags()
behaves the same as munmap() does.
The following bits control the clearing of memory on allocation:
- UNMAP_INIT_REQUIRED
- POSIX initialization of the page to all zeroes is required the
next time the underlying physical memory is allocated.
- UNMAP_INIT_OPTIONAL
- Initialization of the underlying physical memory to zeroes on its
next allocation is optional.
- If you specify the MAP_NOINIT flag to
mmap(),
and the physical memory being mapped was previously unmapped with
UNMAP_INIT_OPTIONAL, the POSIX requirement that the memory
be zeroed is relaxed.
By default, the kernel initializes the memory, but you can control this
by using the -m option to
procnto.
The argument to this option is a string that lets you enable or disable
aspects of the memory manager:
- i
- munmap() acts as if UNMAP_INIT_REQUIRED were
specified.
- ~i
- munmap() acts as if UNMAP_INIT_OPTIONAL were
specified.
By default when memory is freed for later reuse,
the contents of that memory remain untouched; whatever the application
that owned the memory left behind is left intact until the next time
that memory is allocated by another process.
In QNX Neutrino 6.6 and later, the -m option to procnto lets you control
the default behavior when unmapping:
- -mc
- Clear memory when it's freed.
- -m~c
- Don't clear memory when it's freed (the default).
When memory is freed for later reuse,
the contents of that memory remain untouched; whatever the application
that owned the memory left behind is left intact until the next time
that memory is allocated by another process.
At that point, before the memory is handed to the next process, it's zeroed.