During fork, the parent process checkpoints LibOS-managed memory regions and the child process restores them at the exact same addresses. However, the child process's main executable (libpal.so) may be mapped randomly because we don't use fork for this emulation (which would preserve the libpal.so memory mapping) but execve (which allows Linux host to perform ASLR on libpal.so). This leads to transient failures of the child because its libpal.so's memory region may overlap with restored-from-checkpoint memory regions.
This commit restricts the memory range accessible to LibOS for memory management. Since Linux allocates from the top of the x86-64 address range (in approx. 0x7f... range), we hard-code a max available address for LibOS memory management to definitely not overlap with 0x7f... range.
Description of the changes
During fork, the parent process checkpoints LibOS-managed memory regions and the child process restores them at the exact same addresses. However, the child process's main executable (
libpal.so
) may be mapped randomly because we don't use fork for this emulation (which would preserve the libpal.so memory mapping) but execve (which allows Linux host to perform ASLR onlibpal.so
). This leads to transient failures of the child because itslibpal.so
's memory region may overlap with restored-from-checkpoint memory regions.This commit restricts the memory range accessible to LibOS for memory management. Since Linux allocates from the top of the x86-64 address range (in approx.
0x7f...
range), we hard-code a max available address for LibOS memory management to definitely not overlap with0x7f...
range.For more context, see https://github.com/oscarlab/graphene/issues/2589.
Fixes #2589.
How to test this PR?
Try stress-ng manually (#2589).
This change is