diff options
author | Yuta Saito <[email protected]> | 2023-11-22 16:08:53 +0000 |
---|---|---|
committer | Yuta Saito <[email protected]> | 2023-11-23 02:15:42 +0900 |
commit | 0e59d91eeddcff4a28add1ce7796ee9cd9ae9e10 (patch) | |
tree | ca31c2fb81d8c762580641f9d66d7f9c4f9b5a9b /wasm/setjmp.c | |
parent | c1fc1a00ea9633961153451d0e927db49c1b268d (diff) |
[wasm] Avoid malloc during longjmp
`longjmp` can be called to raise `NoMemoryError` or to trigger GC when
`malloc` fails to allocate memory in `ruby_xmalloc` family. In such
case, `malloc` call in `longjmp` will fail again, and Asyncify unwinding
operation corrupts the memory space by using the failed pointer as
Asyncify buffer. This commit uses statically allocated buffer to avoid
such situation.
Diffstat (limited to 'wasm/setjmp.c')
-rw-r--r-- | wasm/setjmp.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/wasm/setjmp.c b/wasm/setjmp.c index 198d210bbf..ebbf8949c1 100644 --- a/wasm/setjmp.c +++ b/wasm/setjmp.c @@ -101,7 +101,6 @@ _rb_wasm_setjmp_internal(rb_wasm_jmp_buf *env) asyncify_stop_rewind(); RB_WASM_DEBUG_LOG(" JMP_BUF_STATE_RETURNING"); env->state = JMP_BUF_STATE_CAPTURED; - free(env->longjmp_buf_ptr); _rb_wasm_active_jmpbuf = NULL; return env->payload; } @@ -119,7 +118,10 @@ _rb_wasm_longjmp(rb_wasm_jmp_buf* env, int value) assert(value != 0); env->state = JMP_BUF_STATE_RETURNING; env->payload = value; - env->longjmp_buf_ptr = malloc(sizeof(struct __rb_wasm_asyncify_jmp_buf)); + // Asyncify buffer built during unwinding for longjmp will not + // be used to rewind, so re-use static-variable. + static struct __rb_wasm_asyncify_jmp_buf tmp_longjmp_buf; + env->longjmp_buf_ptr = &tmp_longjmp_buf; _rb_wasm_active_jmpbuf = env; async_buf_init(env->longjmp_buf_ptr); asyncify_start_unwind(env->longjmp_buf_ptr); |