Skip to content

Commit

Permalink
[LibOS] Extend locking of mprotect() during checkpointing
Browse files Browse the repository at this point in the history
Checkpointing may fail if it assumes memory protection flags that
have not been set on the memory, yet. Therefore, make the code
sequence of

  bkeep_mprotect()

  ...

  PalVirtualMemoryProtect()

atomic so that tracked memory protection flags have also been applied to
the memory.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
  • Loading branch information
stefanberger committed Feb 27, 2024
1 parent ee35346 commit 4879980
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions libos/src/sys/libos_mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,11 @@ long libos_syscall_mprotect(void* addr, size_t length, int prot) {
/* `bkeep_mprotect` and then `PalVirtualMemoryProtect` is racy, but it's hard to do it properly.
* On the other hand if this race happens, it means user app is buggy, so not a huge problem. */

rwlock_read_lock(&checkpoint_lock);

ret = bkeep_mprotect(addr, length, prot, /*is_internal=*/false);
if (ret < 0) {
return ret;
goto error;
}

if (prot & PROT_GROWSDOWN) {
Expand All @@ -323,12 +325,11 @@ long libos_syscall_mprotect(void* addr, size_t length, int prot) {
} else {
log_warning("Memory that was about to be mprotected was unmapped, your program is "
"buggy!");
return -ENOTRECOVERABLE;
ret = -ENOTRECOVERABLE;
goto error;
}
}

rwlock_read_lock(&checkpoint_lock);

ret = PalVirtualMemoryProtect(addr, length, LINUX_PROT_TO_PAL(prot, /*map_flags=*/0));

rwlock_read_unlock(&checkpoint_lock);
Expand All @@ -338,6 +339,11 @@ long libos_syscall_mprotect(void* addr, size_t length, int prot) {
}

return 0;

error:
rwlock_read_unlock(&checkpoint_lock);

return ret;
}

long libos_syscall_munmap(void* _addr, size_t length) {
Expand Down

0 comments on commit 4879980

Please sign in to comment.