mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-09-04 21:23:10 +02:00
Remove exceptions from the sandbox implementation in libretro builds
This commit is contained in:
parent
d0b211e239
commit
0d07aff3e2
6 changed files with 84 additions and 108 deletions
|
@ -83,7 +83,7 @@ wasm_ptr_t binding_base::sandbox_malloc(wasm_size_t size) {
|
||||||
|
|
||||||
// Verify that the entire allocated buffer is in valid memory
|
// Verify that the entire allocated buffer is in valid memory
|
||||||
wasm_ptr_t buf_end;
|
wasm_ptr_t buf_end;
|
||||||
if (buf == 0 || __builtin_add_overflow(buf, size, &buf_end) || buf_end >= instance().w2c_memory.size) {
|
if (buf == 0 || (buf_end = buf + size) < buf || buf_end >= instance().w2c_memory.size) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,8 @@ usize sandbox::sandbox_malloc(usize size) {
|
||||||
|
|
||||||
// Verify that the returned pointer is non-null and the entire allocated buffer is in valid memory
|
// Verify that the returned pointer is non-null and the entire allocated buffer is in valid memory
|
||||||
usize buf_end;
|
usize buf_end;
|
||||||
if (buf == WASM_NULL || __builtin_add_overflow(buf, size, &buf_end) || buf_end >= ruby->w2c_memory.size) {
|
if (buf == WASM_NULL || (buf_end = buf + size) < buf || buf_end >= ruby->w2c_memory.size) {
|
||||||
throw SandboxOutOfMemoryException();
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
|
@ -58,7 +58,6 @@ void sandbox::sandbox_free(usize ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sandbox::sandbox() : ruby(new struct w2c_ruby), wasi(new wasi_t(ruby)), bindings(ruby), yielding(false), transitioning(false) {
|
sandbox::sandbox() : ruby(new struct w2c_ruby), wasi(new wasi_t(ruby)), bindings(ruby), yielding(false), transitioning(false) {
|
||||||
try {
|
|
||||||
// Initialize the sandbox
|
// Initialize the sandbox
|
||||||
wasm2c_ruby_instantiate(RB, wasi.get());
|
wasm2c_ruby_instantiate(RB, wasi.get());
|
||||||
w2c_ruby_mkxp_sandbox_init(
|
w2c_ruby_mkxp_sandbox_init(
|
||||||
|
@ -120,7 +119,7 @@ sandbox::sandbox() : ruby(new struct w2c_ruby), wasi(new wasi_t(ruby)), bindings
|
||||||
AWAIT(state = w2c_ruby_ruby_exec_node(RB, node));
|
AWAIT(state = w2c_ruby_ruby_exec_node(RB, node));
|
||||||
}
|
}
|
||||||
if (!valid || state) {
|
if (!valid || state) {
|
||||||
throw SandboxNodeException();
|
std::abort();
|
||||||
}
|
}
|
||||||
sandbox_free(state_buf);
|
sandbox_free(state_buf);
|
||||||
|
|
||||||
|
@ -131,10 +130,6 @@ sandbox::sandbox() : ruby(new struct w2c_ruby), wasi(new wasi_t(ruby)), bindings
|
||||||
AWAIT(enc = w2c_ruby_rb_enc_from_encoding(RB, encoding));
|
AWAIT(enc = w2c_ruby_rb_enc_from_encoding(RB, encoding));
|
||||||
AWAIT(w2c_ruby_rb_enc_set_default_internal(RB, enc));
|
AWAIT(w2c_ruby_rb_enc_set_default_internal(RB, enc));
|
||||||
AWAIT(w2c_ruby_rb_enc_set_default_external(RB, enc));
|
AWAIT(w2c_ruby_rb_enc_set_default_external(RB, enc));
|
||||||
} catch (SandboxException &) {
|
|
||||||
wasm2c_ruby_free(RB);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sandbox::~sandbox() {
|
sandbox::~sandbox() {
|
||||||
|
|
|
@ -53,12 +53,4 @@ typedef float f32;
|
||||||
typedef double f64;
|
typedef double f64;
|
||||||
#endif // WASM_RT_CORE_TYPES_DEFINED
|
#endif // WASM_RT_CORE_TYPES_DEFINED
|
||||||
|
|
||||||
struct SandboxException {};
|
|
||||||
// The call to `ruby_executable_node()` or `ruby_exec_node()` failed when initializing Ruby.
|
|
||||||
struct SandboxNodeException : SandboxException {};
|
|
||||||
// Failed to allocate memory.
|
|
||||||
struct SandboxOutOfMemoryException : SandboxException {};
|
|
||||||
// An exception occurred inside of Ruby and was not caught.
|
|
||||||
struct SandboxTrapException : SandboxException {};
|
|
||||||
|
|
||||||
#endif // MKXPZ_SANDBOX_TYPES_H
|
#endif // MKXPZ_SANDBOX_TYPES_H
|
||||||
|
|
|
@ -805,7 +805,7 @@ extern "C" u32 w2c_wasi__snapshot__preview1_poll_oneoff(wasi_t *wasi, usize in,
|
||||||
|
|
||||||
extern "C" void w2c_wasi__snapshot__preview1_proc_exit(wasi_t *wasi, u32 rval) {
|
extern "C" void w2c_wasi__snapshot__preview1_proc_exit(wasi_t *wasi, u32 rval) {
|
||||||
WASI_DEBUG("proc_exit(%u)\n", rval);
|
WASI_DEBUG("proc_exit(%u)\n", rval);
|
||||||
throw SandboxTrapException();
|
std::abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" u32 w2c_wasi__snapshot__preview1_random_get(wasi_t *wasi, usize buf, u32 buf_len) {
|
extern "C" u32 w2c_wasi__snapshot__preview1_random_get(wasi_t *wasi, usize buf, u32 buf_len) {
|
||||||
|
|
|
@ -291,7 +291,7 @@ PRELUDE = <<~HEREDOC
|
||||||
bindings::rb_data_type::rb_data_type(wasm_ptr_t ptr) : ptr(ptr) {}
|
bindings::rb_data_type::rb_data_type(wasm_ptr_t ptr) : ptr(ptr) {}
|
||||||
|
|
||||||
wasm_ptr_t bindings::rb_data_type::get() const {
|
wasm_ptr_t bindings::rb_data_type::get() const {
|
||||||
if (ptr == 0) throw SandboxTrapException();
|
if (ptr == 0) std::abort();
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,12 +309,12 @@ POSTSCRIPT = <<~HEREDOC
|
||||||
|
|
||||||
buf = sandbox_malloc(9 * sizeof(wasm_ptr_t));
|
buf = sandbox_malloc(9 * sizeof(wasm_ptr_t));
|
||||||
if (buf == 0) {
|
if (buf == 0) {
|
||||||
throw SandboxOutOfMemoryException();
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
str = sandbox_malloc(std::strlen(wrap_struct_name) + 1);
|
str = sandbox_malloc(std::strlen(wrap_struct_name) + 1);
|
||||||
if (str == 0) {
|
if (str == 0) {
|
||||||
sandbox_free(buf);
|
sandbox_free(buf);
|
||||||
throw SandboxOutOfMemoryException();
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::strcpy((char *)(**this + str), wrap_struct_name);
|
std::strcpy((char *)(**this + str), wrap_struct_name);
|
||||||
|
@ -480,7 +480,7 @@ File.readlines('tags', chomp: true).each do |line|
|
||||||
end
|
end
|
||||||
coroutine_initializer += <<~HEREDOC
|
coroutine_initializer += <<~HEREDOC
|
||||||
default:
|
default:
|
||||||
throw SandboxTrapException();
|
std::abort();
|
||||||
}
|
}
|
||||||
HEREDOC
|
HEREDOC
|
||||||
else
|
else
|
||||||
|
@ -498,7 +498,7 @@ File.readlines('tags', chomp: true).each do |line|
|
||||||
elsif !handler[:buf_size].nil?
|
elsif !handler[:buf_size].nil?
|
||||||
coroutine_initializer += <<~HEREDOC
|
coroutine_initializer += <<~HEREDOC
|
||||||
f#{i} = bind.sandbox_malloc(#{handler[:buf_size].gsub('PREV_ARG', "a#{i - 1}").gsub('ARG', "a#{i}")});
|
f#{i} = bind.sandbox_malloc(#{handler[:buf_size].gsub('PREV_ARG', "a#{i - 1}").gsub('ARG', "a#{i}")});
|
||||||
if (f#{i} == 0) throw SandboxOutOfMemoryException();
|
if (f#{i} == 0) throw std::bad_alloc();
|
||||||
HEREDOC
|
HEREDOC
|
||||||
coroutine_initializer += handler[:serialize].gsub('PREV_ARG', "a#{i - 1}").gsub('ARG', "a#{i}").gsub('BUF', "f#{i}")
|
coroutine_initializer += handler[:serialize].gsub('PREV_ARG', "a#{i - 1}").gsub('ARG', "a#{i}").gsub('BUF', "f#{i}")
|
||||||
coroutine_initializer += "\n"
|
coroutine_initializer += "\n"
|
||||||
|
@ -523,7 +523,7 @@ File.readlines('tags', chomp: true).each do |line|
|
||||||
fp = w2c_ruby_rb_wasm_get_stack_pointer(&bind.instance());
|
fp = w2c_ruby_rb_wasm_get_stack_pointer(&bind.instance());
|
||||||
sp = fp - CEIL_WASMSTACKALIGN(a#{args.length - 2} * sizeof(VALUE));
|
sp = fp - CEIL_WASMSTACKALIGN(a#{args.length - 2} * sizeof(VALUE));
|
||||||
if (sp > fp) {
|
if (sp > fp) {
|
||||||
throw SandboxOutOfMemoryException();
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
w2c_ruby_rb_wasm_set_stack_pointer(&bind.instance(), sp);
|
w2c_ruby_rb_wasm_set_stack_pointer(&bind.instance(), sp);
|
||||||
std::va_list a;
|
std::va_list a;
|
||||||
|
@ -550,7 +550,7 @@ File.readlines('tags', chomp: true).each do |line|
|
||||||
fp = w2c_ruby_rb_wasm_get_stack_pointer(&bind.instance());
|
fp = w2c_ruby_rb_wasm_get_stack_pointer(&bind.instance());
|
||||||
sp = fp - CEIL_WASMSTACKALIGN(n * sizeof(VALUE));
|
sp = fp - CEIL_WASMSTACKALIGN(n * sizeof(VALUE));
|
||||||
if (sp > fp) {
|
if (sp > fp) {
|
||||||
throw SandboxOutOfMemoryException();
|
throw std::bad_alloc();
|
||||||
}
|
}
|
||||||
w2c_ruby_rb_wasm_set_stack_pointer(&bind.instance(), sp);
|
w2c_ruby_rb_wasm_set_stack_pointer(&bind.instance(), sp);
|
||||||
for (wasm_size_t i = 0; i < n; ++i) {
|
for (wasm_size_t i = 0; i < n; ++i) {
|
||||||
|
|
11
src/core.cpp
11
src/core.cpp
|
@ -320,13 +320,7 @@ static bool init_sandbox() {
|
||||||
|
|
||||||
audio.emplace(*thread_data);
|
audio.emplace(*thread_data);
|
||||||
|
|
||||||
try {
|
|
||||||
mkxp_retro::sandbox.emplace();
|
mkxp_retro::sandbox.emplace();
|
||||||
} catch (SandboxException) {
|
|
||||||
log_printf(RETRO_LOG_ERROR, "Failed to initialize Ruby\n");
|
|
||||||
deinit_sandbox();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
float refresh_rate;
|
float refresh_rate;
|
||||||
|
@ -467,15 +461,10 @@ extern "C" RETRO_API void retro_run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (should_render) {
|
if (should_render) {
|
||||||
try {
|
|
||||||
if (sb().run<struct main>()) {
|
if (sb().run<struct main>()) {
|
||||||
log_printf(RETRO_LOG_INFO, "[Sandbox] Ruby terminated normally\n");
|
log_printf(RETRO_LOG_INFO, "[Sandbox] Ruby terminated normally\n");
|
||||||
deinit_sandbox();
|
deinit_sandbox();
|
||||||
}
|
}
|
||||||
} catch (SandboxException) {
|
|
||||||
log_printf(RETRO_LOG_ERROR, "[Sandbox] Ruby threw an exception\n");
|
|
||||||
deinit_sandbox();
|
|
||||||
}
|
|
||||||
} else if (!dupe_supported && mkxp_retro::sandbox.has_value()) {
|
} else if (!dupe_supported && mkxp_retro::sandbox.has_value()) {
|
||||||
shState->graphics().repaint(sb().transitioning);
|
shState->graphics().repaint(sb().transitioning);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue