Skip to content

Commit

Permalink
Extend wasi-emulated-mman with mprotect. (#500)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
whitequark authored May 22, 2024
1 parent 44c4b1e commit 7528b13
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 0 deletions.
1 change: 1 addition & 0 deletions expected/wasm32-wasip1-threads/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,7 @@ mmap
modf
modff
modfl
mprotect
mrand48
munmap
nan
Expand Down
1 change: 1 addition & 0 deletions expected/wasm32-wasip1/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,7 @@ mmap
modf
modff
modfl
mprotect
mrand48
munmap
nan
Expand Down
1 change: 1 addition & 0 deletions expected/wasm32-wasip2/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@ monotonic_clock_now
monotonic_clock_resolution
monotonic_clock_subscribe_duration
monotonic_clock_subscribe_instant
mprotect
mrand48
munmap
nan
Expand Down
33 changes: 33 additions & 0 deletions libc-bottom-half/mman/mman.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include <sys/mman.h>
#include <sys/types.h>

Expand Down Expand Up @@ -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;
}

0 comments on commit 7528b13

Please sign in to comment.