Extend wasi-emulated-mman with mprotect. (#500)

This implementation never changes actual memory protection, but it does
verify that the address range and flags are valid. The direct motivation
is fixing a linker error where LLVM links to `mprotect` in dead code.
This commit is contained in:
Catherine 2024-05-22 18:09:22 +01:00 committed by GitHub
parent 44c4b1e3a5
commit 7528b13170
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 36 additions and 0 deletions

View File

@ -928,6 +928,7 @@ mmap
modf
modff
modfl
mprotect
mrand48
munmap
nan

View File

@ -861,6 +861,7 @@ mmap
modf
modff
modfl
mprotect
mrand48
munmap
nan

View File

@ -980,6 +980,7 @@ monotonic_clock_now
monotonic_clock_resolution
monotonic_clock_subscribe_duration
monotonic_clock_subscribe_instant
mprotect
mrand48
munmap
nan

View File

@ -9,6 +9,7 @@
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include <sys/mman.h>
#include <sys/types.h>
@ -122,3 +123,35 @@ int munmap(void *addr, size_t length) {
// Success!
return 0;
}
int mprotect(void *addr, size_t length, int prot) {
// Address must be page-aligned.
size_t begin = (size_t)addr;
if ((begin & (PAGESIZE - 1)) != 0) {
errno = EINVAL;
return -1;
}
// Length must not be big enough to wrap around.
size_t end;
if (__builtin_add_overflow(begin, length, &end)) {
errno = ENOMEM;
return -1;
}
// Range must be in bounds of linear memory.
size_t memory_size = __builtin_wasm_memory_size(0) * PAGESIZE;
if (end > memory_size) {
errno = ENOMEM;
return -1;
}
// Can only protect memory as read/write (which is a no-op).
if (prot != (PROT_READ | PROT_WRITE)) {
errno = ENOTSUP;
return -1;
}
// Success!
return 0;
}