mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-09-10 12:02:53 +02:00
Add bounds checking to operations involving arrays in sandbox memory
This commit is contained in:
parent
ae0e1bd6d5
commit
19fe3f955d
6 changed files with 82 additions and 13 deletions
|
@ -126,6 +126,12 @@ void binding_base::copy_memory_from(const void *ptr, wasm_size_t size, wasm_size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mkxp_sandbox::sandbox_check_bounds(struct w2c_ruby &instance, wasm_ptr_t address, wasm_size_t size) noexcept {
|
||||||
|
if (address >= instance.w2c_memory.size || instance.w2c_memory.size - address < size) {
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wasm_size_t mkxp_sandbox::sandbox_strlen(struct w2c_ruby &instance, wasm_ptr_t address) noexcept {
|
wasm_size_t mkxp_sandbox::sandbox_strlen(struct w2c_ruby &instance, wasm_ptr_t address) noexcept {
|
||||||
const char *ptr = &sandbox_ref<char>(instance, address);
|
const char *ptr = &sandbox_ref<char>(instance, address);
|
||||||
#ifdef MKXPZ_BIG_ENDIAN
|
#ifdef MKXPZ_BIG_ENDIAN
|
||||||
|
@ -171,6 +177,10 @@ void mkxp_sandbox::sandbox_strncpy_s(struct w2c_ruby &instance, wasm_ptr_t dst_a
|
||||||
sandbox_arycpy(instance, dst_address, src, std::min((wasm_size_t)std::strlen(src) + 1, max_size));
|
sandbox_arycpy(instance, dst_address, src, std::min((wasm_size_t)std::strlen(src) + 1, max_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void binding_base::check_bounds(wasm_ptr_t address, wasm_size_t size) const noexcept {
|
||||||
|
return sandbox_check_bounds(instance(), address, size);
|
||||||
|
}
|
||||||
|
|
||||||
wasm_size_t binding_base::strlen(wasm_ptr_t address) const noexcept {
|
wasm_size_t binding_base::strlen(wasm_ptr_t address) const noexcept {
|
||||||
return sandbox_strlen(instance(), address);
|
return sandbox_strlen(instance(), address);
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,10 @@ namespace mkxp_sandbox {
|
||||||
return sandbox_ref<T>(array_address + array_index * sizeof(T));
|
return sandbox_ref<T>(array_address + array_index * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if the array with the given address and size in bytes is within the bounds of sandbox memory.
|
||||||
|
// If it isn't, aborts. Otherwise, does nothing.
|
||||||
|
void sandbox_check_bounds(struct w2c_ruby &instance, wasm_ptr_t address, wasm_size_t size) noexcept;
|
||||||
|
|
||||||
// Gets the length of a string stored at a given address in sandbox memory.
|
// Gets the length of a string stored at a given address in sandbox memory.
|
||||||
wasm_size_t sandbox_strlen(struct w2c_ruby &instance, wasm_ptr_t address) noexcept;
|
wasm_size_t sandbox_strlen(struct w2c_ruby &instance, wasm_ptr_t address) noexcept;
|
||||||
|
|
||||||
|
@ -387,6 +391,10 @@ namespace mkxp_sandbox {
|
||||||
return ref<T>(array_address + array_index * sizeof(T));
|
return ref<T>(array_address + array_index * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if the array with the given address and size in bytes is within the bounds of sandbox memory.
|
||||||
|
// If it isn't, aborts. Otherwise, does nothing.
|
||||||
|
void check_bounds(wasm_ptr_t address, wasm_size_t size) const noexcept;
|
||||||
|
|
||||||
// Gets the length of a string stored at a given address in sandbox memory.
|
// Gets the length of a string stored at a given address in sandbox memory.
|
||||||
wasm_size_t strlen(wasm_ptr_t address) const noexcept;
|
wasm_size_t strlen(wasm_ptr_t address) const noexcept;
|
||||||
|
|
||||||
|
|
|
@ -407,12 +407,15 @@ static VALUE get_raw_data(VALUE self) {
|
||||||
SANDBOX_AWAIT_S(1, rb_str_new_cstr, "");
|
SANDBOX_AWAIT_S(1, rb_str_new_cstr, "");
|
||||||
SANDBOX_AWAIT(rb_str_resize, SANDBOX_SLOT(1), SANDBOX_SLOT(2));
|
SANDBOX_AWAIT(rb_str_resize, SANDBOX_SLOT(1), SANDBOX_SLOT(2));
|
||||||
SANDBOX_AWAIT_S(0, rb_string_value_ptr, &SANDBOX_SLOT(1));
|
SANDBOX_AWAIT_S(0, rb_string_value_ptr, &SANDBOX_SLOT(1));
|
||||||
|
if (SANDBOX_SLOT(2) > 0) {
|
||||||
|
sb()->check_bounds(SANDBOX_SLOT(0), SANDBOX_SLOT(2));
|
||||||
#ifdef MKXPZ_BIG_ENDIAN
|
#ifdef MKXPZ_BIG_ENDIAN
|
||||||
SANDBOX_GUARD_L(bitmap->getRaw(sb().e, &sb()->ref<uint8_t>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(2), (int32_t)1) - 1), SANDBOX_SLOT(2)));
|
SANDBOX_GUARD_L(bitmap->getRaw(sb().e, &sb()->ref<uint8_t>(SANDBOX_SLOT(0), SANDBOX_SLOT(2) - 1), SANDBOX_SLOT(2)));
|
||||||
std::reverse(&sb()->ref<uint8_t>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(2), (int32_t)1) - 1), &sb()->ref<uint8_t>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(2), (int32_t)1) - 1) + SANDBOX_SLOT(2));
|
std::reverse(&sb()->ref<uint8_t>(SANDBOX_SLOT(0), SANDBOX_SLOT(2) - 1), &sb()->ref<uint8_t>(SANDBOX_SLOT(0), SANDBOX_SLOT(2) - 1) + SANDBOX_SLOT(2));
|
||||||
#else
|
#else
|
||||||
SANDBOX_GUARD_L(bitmap->getRaw(sb().e, &sb()->ref<uint8_t>(SANDBOX_SLOT(0)), SANDBOX_SLOT(2)));
|
SANDBOX_GUARD_L(bitmap->getRaw(sb().e, &sb()->ref<uint8_t>(SANDBOX_SLOT(0)), SANDBOX_SLOT(2)));
|
||||||
#endif // MKXPZ_BIG_ENDIAN
|
#endif // MKXPZ_BIG_ENDIAN
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SANDBOX_SLOT(1);
|
return SANDBOX_SLOT(1);
|
||||||
|
@ -430,12 +433,15 @@ static VALUE set_raw_data(VALUE self, VALUE value) {
|
||||||
BOOST_ASIO_CORO_REENTER (this) {
|
BOOST_ASIO_CORO_REENTER (this) {
|
||||||
SANDBOX_AWAIT_S(0, rb_string_value_ptr, &value);
|
SANDBOX_AWAIT_S(0, rb_string_value_ptr, &value);
|
||||||
SANDBOX_AWAIT_S(1, get_bytesize, value);
|
SANDBOX_AWAIT_S(1, get_bytesize, value);
|
||||||
|
if (SANDBOX_SLOT(1) > 0) {
|
||||||
|
sb()->check_bounds(SANDBOX_SLOT(0), SANDBOX_SLOT(1));
|
||||||
#ifdef MKXPZ_BIG_ENDIAN
|
#ifdef MKXPZ_BIG_ENDIAN
|
||||||
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->replaceRaw(sb().e, &sb()->ref<uint8_t>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(1), (int32_t)1) - 1), SANDBOX_SLOT(1)));
|
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->replaceRaw(sb().e, &sb()->ref<uint8_t>(SANDBOX_SLOT(0), SANDBOX_SLOT(1) - 1), SANDBOX_SLOT(1)));
|
||||||
std::reverse(&sb()->ref<uint8_t>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(1), (int32_t)1) - 1), &sb()->ref<uint8_t>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(1), (int32_t)1) - 1) + SANDBOX_SLOT(1));
|
std::reverse(&sb()->ref<uint8_t>(SANDBOX_SLOT(0), SANDBOX_SLOT(1) - 1), &sb()->ref<uint8_t>(SANDBOX_SLOT(0), SANDBOX_SLOT(1) - 1) + SANDBOX_SLOT(1));
|
||||||
#else
|
#else
|
||||||
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->replaceRaw(sb().e, &sb()->ref<uint8_t>(SANDBOX_SLOT(0)), SANDBOX_SLOT(1)));
|
SANDBOX_GUARD_L(get_private_data<Bitmap>(self)->replaceRaw(sb().e, &sb()->ref<uint8_t>(SANDBOX_SLOT(0)), SANDBOX_SLOT(1)));
|
||||||
#endif // MKXPZ_BIG_ENDIAN
|
#endif // MKXPZ_BIG_ENDIAN
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
|
@ -35,13 +35,16 @@ namespace mkxp_sandbox {
|
||||||
SANDBOX_AWAIT_S(2, rb_obj_alloc, klass);
|
SANDBOX_AWAIT_S(2, rb_obj_alloc, klass);
|
||||||
SANDBOX_AWAIT_S(0, rb_string_value_ptr, &src);
|
SANDBOX_AWAIT_S(0, rb_string_value_ptr, &src);
|
||||||
SANDBOX_AWAIT_S(1, get_bytesize, src);
|
SANDBOX_AWAIT_S(1, get_bytesize, src);
|
||||||
|
if (SANDBOX_SLOT(1) > 0) {
|
||||||
|
sb()->check_bounds(SANDBOX_SLOT(0), SANDBOX_SLOT(1));
|
||||||
#ifdef MKXPZ_BIG_ENDIAN
|
#ifdef MKXPZ_BIG_ENDIAN
|
||||||
std::reverse(&sb()->ref<char>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(1), (wasm_size_t)1) - 1), &sb()->ref<char>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(1), (wasm_size_t)1) - 1) + SANDBOX_SLOT(1));
|
std::reverse(&sb()->ref<char>(SANDBOX_SLOT(0), SANDBOX_SLOT(1) - 1), &sb()->ref<char>(SANDBOX_SLOT(0), SANDBOX_SLOT(1) - 1) + SANDBOX_SLOT(1));
|
||||||
SANDBOX_GUARD(set_private_data(sb().e, SANDBOX_SLOT(2), C::deserialize(sb().e, &sb()->ref<char>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(1), (wasm_size_t)1) - 1), SANDBOX_SLOT(1))));
|
SANDBOX_GUARD(set_private_data(sb().e, SANDBOX_SLOT(2), C::deserialize(sb().e, &sb()->ref<char>(SANDBOX_SLOT(0), SANDBOX_SLOT(1) - 1), SANDBOX_SLOT(1))));
|
||||||
std::reverse(&sb()->ref<char>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(1), (wasm_size_t)1) - 1), &sb()->ref<char>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(1), (wasm_size_t)1) - 1) + SANDBOX_SLOT(1));
|
std::reverse(&sb()->ref<char>(SANDBOX_SLOT(0), SANDBOX_SLOT(1) - 1), &sb()->ref<char>(SANDBOX_SLOT(0), SANDBOX_SLOT(1) - 1) + SANDBOX_SLOT(1));
|
||||||
#else
|
#else
|
||||||
SANDBOX_GUARD(set_private_data(sb().e, SANDBOX_SLOT(2), C::deserialize(sb().e, &sb()->ref<char>(SANDBOX_SLOT(0)), SANDBOX_SLOT(1))));
|
SANDBOX_GUARD(set_private_data(sb().e, SANDBOX_SLOT(2), C::deserialize(sb().e, &sb()->ref<char>(SANDBOX_SLOT(0)), SANDBOX_SLOT(1))));
|
||||||
#endif // MKXPZ_BIG_ENDIAN
|
#endif // MKXPZ_BIG_ENDIAN
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SANDBOX_SLOT(2);
|
return SANDBOX_SLOT(2);
|
||||||
|
@ -61,12 +64,15 @@ namespace mkxp_sandbox {
|
||||||
SANDBOX_AWAIT_S(2, rb_str_new_cstr, "");
|
SANDBOX_AWAIT_S(2, rb_str_new_cstr, "");
|
||||||
SANDBOX_AWAIT(rb_str_resize, SANDBOX_SLOT(2), SANDBOX_SLOT(1));
|
SANDBOX_AWAIT(rb_str_resize, SANDBOX_SLOT(2), SANDBOX_SLOT(1));
|
||||||
SANDBOX_AWAIT_S(0, rb_string_value_ptr, &SANDBOX_SLOT(2));
|
SANDBOX_AWAIT_S(0, rb_string_value_ptr, &SANDBOX_SLOT(2));
|
||||||
|
if (SANDBOX_SLOT(1) > 0) {
|
||||||
|
sb()->check_bounds(SANDBOX_SLOT(0), SANDBOX_SLOT(1));
|
||||||
#ifdef MKXPZ_BIG_ENDIAN
|
#ifdef MKXPZ_BIG_ENDIAN
|
||||||
get_private_data<C>(self)->serialize(&sb()->ref<char>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(1), (wasm_size_t)1) - 1));
|
get_private_data<C>(self)->serialize(&sb()->ref<char>(SANDBOX_SLOT(0), SANDBOX_SLOT(1) - 1));
|
||||||
std::reverse(&sb()->ref<char>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(1), (wasm_size_t)1) - 1), &sb()->ref<char>(SANDBOX_SLOT(0), std::max(SANDBOX_SLOT(1), (wasm_size_t)1) - 1) + SANDBOX_SLOT(1));
|
std::reverse(&sb()->ref<char>(SANDBOX_SLOT(0), SANDBOX_SLOT(1) - 1), &sb()->ref<char>(SANDBOX_SLOT(0), SANDBOX_SLOT(1) - 1) + SANDBOX_SLOT(1));
|
||||||
#else
|
#else
|
||||||
get_private_data<C>(self)->serialize(&sb()->ref<char>(SANDBOX_SLOT(0)));
|
get_private_data<C>(self)->serialize(&sb()->ref<char>(SANDBOX_SLOT(0)));
|
||||||
#endif // MKXPZ_BIG_ENDIAN
|
#endif // MKXPZ_BIG_ENDIAN
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SANDBOX_SLOT(2);
|
return SANDBOX_SLOT(2);
|
||||||
|
|
|
@ -138,6 +138,10 @@ void wasi_t::deallocate_file_descriptor(uint32_t fd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wasi_t::check_bounds(mkxp_sandbox::wasm_ptr_t address, mkxp_sandbox::wasm_size_t size) const noexcept {
|
||||||
|
sandbox_check_bounds(*ruby, address, size);
|
||||||
|
}
|
||||||
|
|
||||||
wasm_size_t wasi_t::strlen(wasm_ptr_t address) const noexcept {
|
wasm_size_t wasi_t::strlen(wasm_ptr_t address) const noexcept {
|
||||||
return sandbox_strlen(*ruby, address);
|
return sandbox_strlen(*ruby, address);
|
||||||
}
|
}
|
||||||
|
@ -541,6 +545,12 @@ extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_filestat_set_size(wasi_t *wa
|
||||||
|
|
||||||
extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_pread(wasi_t *wasi, uint32_t fd, wasm_ptr_t iovs, uint32_t iovs_len, uint64_t offset, wasm_ptr_t result) {
|
extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_pread(wasi_t *wasi, uint32_t fd, wasm_ptr_t iovs, uint32_t iovs_len, uint64_t offset, wasm_ptr_t result) {
|
||||||
WASI_DEBUG("fd_pread(%u, 0x%08x (%u), %lu)\n", fd, iovs, iovs_len, offset);
|
WASI_DEBUG("fd_pread(%u, 0x%08x (%u), %lu)\n", fd, iovs, iovs_len, offset);
|
||||||
|
|
||||||
|
if (8 * (wasm_size_t)iovs_len <= (wasm_size_t)iovs_len) {
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
wasi->check_bounds(iovs, 8 * (wasm_size_t)iovs_len);
|
||||||
|
|
||||||
return WASI_ENOSYS;
|
return WASI_ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,12 +609,23 @@ extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_prestat_get(wasi_t *wasi, ui
|
||||||
|
|
||||||
extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_pwrite(wasi_t *wasi, uint32_t fd, wasm_ptr_t iovs, uint32_t iovs_len, uint64_t offset, wasm_ptr_t result) {
|
extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_pwrite(wasi_t *wasi, uint32_t fd, wasm_ptr_t iovs, uint32_t iovs_len, uint64_t offset, wasm_ptr_t result) {
|
||||||
WASI_DEBUG("fd_pwrite(%u, 0x%08x (%u), %lu)\n", fd, iovs, iovs_len, offset);
|
WASI_DEBUG("fd_pwrite(%u, 0x%08x (%u), %lu)\n", fd, iovs, iovs_len, offset);
|
||||||
|
|
||||||
|
if (8 * (wasm_size_t)iovs_len <= (wasm_size_t)iovs_len) {
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
wasi->check_bounds(iovs, 8 * (wasm_size_t)iovs_len);
|
||||||
|
|
||||||
return WASI_ENOSYS;
|
return WASI_ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_read(wasi_t *wasi, uint32_t fd, wasm_ptr_t iovs, uint32_t iovs_len, wasm_ptr_t result) {
|
extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_read(wasi_t *wasi, uint32_t fd, wasm_ptr_t iovs, uint32_t iovs_len, wasm_ptr_t result) {
|
||||||
WASI_DEBUG("fd_read(%u, 0x%08x (%u))\n", fd, iovs, iovs_len);
|
WASI_DEBUG("fd_read(%u, 0x%08x (%u))\n", fd, iovs, iovs_len);
|
||||||
|
|
||||||
|
if (8 * (wasm_size_t)iovs_len <= (wasm_size_t)iovs_len) {
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
wasi->check_bounds(iovs, 8 * (wasm_size_t)iovs_len);
|
||||||
|
|
||||||
if (fd >= wasi->fdtable.size()) {
|
if (fd >= wasi->fdtable.size()) {
|
||||||
return WASI_EBADF;
|
return WASI_EBADF;
|
||||||
}
|
}
|
||||||
|
@ -630,6 +651,7 @@ extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_read(wasi_t *wasi, uint32_t
|
||||||
uint32_t ptr = wasi->ref<uint32_t>(iovs);
|
uint32_t ptr = wasi->ref<uint32_t>(iovs);
|
||||||
uint32_t length = wasi->ref<uint32_t>(iovs + 4);
|
uint32_t length = wasi->ref<uint32_t>(iovs + 4);
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
|
wasi->check_bounds(ptr, length);
|
||||||
#ifdef MKXPZ_BIG_ENDIAN
|
#ifdef MKXPZ_BIG_ENDIAN
|
||||||
uint8_t *buffer = &wasi->ref<uint8_t>(ptr, length - 1);
|
uint8_t *buffer = &wasi->ref<uint8_t>(ptr, length - 1);
|
||||||
#else
|
#else
|
||||||
|
@ -656,6 +678,8 @@ extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_read(wasi_t *wasi, uint32_t
|
||||||
extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_readdir(wasi_t *wasi, uint32_t fd, wasm_ptr_t buf, uint32_t buf_len, uint64_t cookie, wasm_ptr_t result) {
|
extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_readdir(wasi_t *wasi, uint32_t fd, wasm_ptr_t buf, uint32_t buf_len, uint64_t cookie, wasm_ptr_t result) {
|
||||||
WASI_DEBUG("fd_readdir(%u, 0x%08x (%u), %lu)\n", fd, buf, buf_len, cookie);
|
WASI_DEBUG("fd_readdir(%u, 0x%08x (%u), %lu)\n", fd, buf, buf_len, cookie);
|
||||||
|
|
||||||
|
wasi->check_bounds(buf, buf_len);
|
||||||
|
|
||||||
if (fd >= wasi->fdtable.size()) {
|
if (fd >= wasi->fdtable.size()) {
|
||||||
return WASI_EBADF;
|
return WASI_EBADF;
|
||||||
}
|
}
|
||||||
|
@ -850,6 +874,11 @@ extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_tell(wasi_t *wasi, uint32_t
|
||||||
extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_write(wasi_t *wasi, uint32_t fd, wasm_ptr_t iovs, uint32_t iovs_len, wasm_ptr_t result) {
|
extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_write(wasi_t *wasi, uint32_t fd, wasm_ptr_t iovs, uint32_t iovs_len, wasm_ptr_t result) {
|
||||||
WASI_DEBUG("fd_write(%u, 0x%08x (%u))\n", fd, iovs, iovs_len);
|
WASI_DEBUG("fd_write(%u, 0x%08x (%u))\n", fd, iovs, iovs_len);
|
||||||
|
|
||||||
|
if (8 * (wasm_size_t)iovs_len <= (wasm_size_t)iovs_len) {
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
wasi->check_bounds(iovs, 8 * (wasm_size_t)iovs_len);
|
||||||
|
|
||||||
if (fd >= wasi->fdtable.size()) {
|
if (fd >= wasi->fdtable.size()) {
|
||||||
return WASI_EBADF;
|
return WASI_EBADF;
|
||||||
}
|
}
|
||||||
|
@ -897,6 +926,7 @@ extern "C" uint32_t w2c_wasi__snapshot__preview1_fd_write(wasi_t *wasi, uint32_t
|
||||||
uint32_t ptr = wasi->ref<uint32_t>(iovs);
|
uint32_t ptr = wasi->ref<uint32_t>(iovs);
|
||||||
uint32_t length = wasi->ref<uint32_t>(iovs + 4);
|
uint32_t length = wasi->ref<uint32_t>(iovs + 4);
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
|
wasi->check_bounds(ptr, length);
|
||||||
#ifdef MKXPZ_BIG_ENDIAN
|
#ifdef MKXPZ_BIG_ENDIAN
|
||||||
uint8_t *buffer = &wasi->ref<uint8_t>(ptr, length - 1);
|
uint8_t *buffer = &wasi->ref<uint8_t>(ptr, length - 1);
|
||||||
std::reverse(buffer, buffer + length);
|
std::reverse(buffer, buffer + length);
|
||||||
|
@ -1102,6 +1132,9 @@ extern "C" uint32_t w2c_wasi__snapshot__preview1_path_open(wasi_t *wasi, uint32_
|
||||||
|
|
||||||
extern "C" uint32_t w2c_wasi__snapshot__preview1_path_readlink(wasi_t *wasi, uint32_t fd, wasm_ptr_t path, uint32_t path_len, wasm_ptr_t buf, uint32_t buf_len, wasm_ptr_t result) {
|
extern "C" uint32_t w2c_wasi__snapshot__preview1_path_readlink(wasi_t *wasi, uint32_t fd, wasm_ptr_t path, uint32_t path_len, wasm_ptr_t buf, uint32_t buf_len, wasm_ptr_t result) {
|
||||||
WASI_DEBUG("path_readlink(%u, \"%.*s\", 0x%08x (%u))\n", fd, path_len, (const char *)wasi->str(path), buf, buf_len);
|
WASI_DEBUG("path_readlink(%u, \"%.*s\", 0x%08x (%u))\n", fd, path_len, (const char *)wasi->str(path), buf, buf_len);
|
||||||
|
|
||||||
|
wasi->check_bounds(buf, buf_len);
|
||||||
|
|
||||||
return WASI_ENOSYS;
|
return WASI_ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1260,6 +1293,8 @@ extern "C" void w2c_wasi__snapshot__preview1_proc_exit(wasi_t *wasi, uint32_t rv
|
||||||
extern "C" uint32_t w2c_wasi__snapshot__preview1_random_get(wasi_t *wasi, wasm_ptr_t buf, uint32_t buf_len) {
|
extern "C" uint32_t w2c_wasi__snapshot__preview1_random_get(wasi_t *wasi, wasm_ptr_t buf, uint32_t buf_len) {
|
||||||
WASI_DEBUG("random_get(0x%08x (%u))\n", buf, buf_len);
|
WASI_DEBUG("random_get(0x%08x (%u))\n", buf, buf_len);
|
||||||
|
|
||||||
|
wasi->check_bounds(buf, buf_len);
|
||||||
|
|
||||||
while (buf_len > 0) {
|
while (buf_len > 0) {
|
||||||
if (wasi->prng_buffer_size == 0) {
|
if (wasi->prng_buffer_size == 0) {
|
||||||
wasi->prng_buffer_size = 4;
|
wasi->prng_buffer_size = 4;
|
||||||
|
|
|
@ -233,6 +233,10 @@ typedef struct w2c_wasi__snapshot__preview1 {
|
||||||
return ref<T>(array_address + array_index * sizeof(T));
|
return ref<T>(array_address + array_index * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if the array with the given address and size in bytes is within the bounds of sandbox memory.
|
||||||
|
// If it isn't, aborts. Otherwise, does nothing.
|
||||||
|
void check_bounds(mkxp_sandbox::wasm_ptr_t address, mkxp_sandbox::wasm_size_t size) const noexcept;
|
||||||
|
|
||||||
// Gets a string stored at a given address in sandbox memory.
|
// Gets a string stored at a given address in sandbox memory.
|
||||||
struct mkxp_sandbox::sandbox_str_guard str(mkxp_sandbox::wasm_ptr_t address) const noexcept;
|
struct mkxp_sandbox::sandbox_str_guard str(mkxp_sandbox::wasm_ptr_t address) const noexcept;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue