From db42972a2112e7e948ff5dada7162d822ed68755 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Tue, 1 Apr 2025 05:49:23 +0000 Subject: [PATCH 1/6] [DNM] Revert memory leak fixes --- ...et-saved_ec.tag-to-NULL-in-cont_init.patch | 26 +++ ...buffer-leak-in-setjmp-handler-in-WAS.patch | 155 ++++++++++++++++++ ...-pointer-corruption-in-setjmp-handle.patch | 63 +++++++ 3 files changed, 244 insertions(+) create mode 100644 patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch create mode 100644 patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch create mode 100644 patches/head/0003-Revert-Fix-stack-pointer-corruption-in-setjmp-handle.patch diff --git a/patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch b/patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch new file mode 100644 index 000000000..adf70c133 --- /dev/null +++ b/patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch @@ -0,0 +1,26 @@ +From 3d186e7edd50ad4e8037f3cd017a19532a5f9a58 Mon Sep 17 00:00:00 2001 +From: Yuta Saito +Date: Tue, 1 Apr 2025 05:48:13 +0000 +Subject: [PATCH 1/3] Revert "Don't set `saved_ec.tag` to `NULL` in + `cont_init()`" + +This reverts commit 372515f33c908b36b3f5fbd2edcb34c69b418500. +--- + cont.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/cont.c b/cont.c +index 072ae4562f..ae68da4e83 100644 +--- a/cont.c ++++ b/cont.c +@@ -1369,6 +1369,7 @@ cont_init(rb_context_t *cont, rb_thread_t *th) + /* save thread context */ + cont_save_thread(cont, th); + cont->saved_ec.thread_ptr = th; ++ cont->saved_ec.tag = NULL; + cont->saved_ec.local_storage = NULL; + cont->saved_ec.local_storage_recursive_hash = Qnil; + cont->saved_ec.local_storage_recursive_hash_for_trace = Qnil; +-- +2.48.1 + diff --git a/patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch b/patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch new file mode 100644 index 000000000..c2688338b --- /dev/null +++ b/patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch @@ -0,0 +1,155 @@ +From 72a19c53d2ef1d3d452ad23fe3efc9e02de3a45c Mon Sep 17 00:00:00 2001 +From: Yuta Saito +Date: Tue, 1 Apr 2025 05:48:27 +0000 +Subject: [PATCH 2/3] Revert "Fix jump buffer leak in setjmp handler in WASI + builds" + +This reverts commit 3a730be8b464454878a42132f6fecb98ab4c1b5b. +--- + cont.c | 1 - + eval_intern.h | 4 +-- + vm_core.h | 77 +++++++++++++++++---------------------------------- + 3 files changed, 27 insertions(+), 55 deletions(-) + +diff --git a/cont.c b/cont.c +index ae68da4e83..072ae4562f 100644 +--- a/cont.c ++++ b/cont.c +@@ -1369,7 +1369,6 @@ cont_init(rb_context_t *cont, rb_thread_t *th) + /* save thread context */ + cont_save_thread(cont, th); + cont->saved_ec.thread_ptr = th; +- cont->saved_ec.tag = NULL; + cont->saved_ec.local_storage = NULL; + cont->saved_ec.local_storage_recursive_hash = Qnil; + cont->saved_ec.local_storage_recursive_hash_for_trace = Qnil; +diff --git a/eval_intern.h b/eval_intern.h +index 49229fa82d..ab0577e8ed 100644 +--- a/eval_intern.h ++++ b/eval_intern.h +@@ -102,11 +102,11 @@ extern int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval + _tag.tag = Qundef; \ + _tag.prev = _ec->tag; \ + _tag.lock_rec = rb_ec_vm_lock_rec(_ec); \ +- rb_vm_tag_jmpbuf_init(&_tag); ++ rb_vm_tag_jmpbuf_init(&_tag.buf); \ + + #define EC_POP_TAG() \ + _ec->tag = _tag.prev; \ +- rb_vm_tag_jmpbuf_deinit(&_tag); \ ++ rb_vm_tag_jmpbuf_deinit(&_tag.buf); \ + } while (0) + + #define EC_TMPPOP_TAG() \ +diff --git a/vm_core.h b/vm_core.h +index 28d742feed..d9159f5ccf 100644 +--- a/vm_core.h ++++ b/vm_core.h +@@ -946,79 +946,52 @@ typedef void *rb_jmpbuf_t[5]; + Therefore, we allocates the buffer on the heap on such + environments. + */ +-typedef struct _rb_vm_tag_jmpbuf { +- struct _rb_vm_tag_jmpbuf *next; +- rb_jmpbuf_t buf; +-} *rb_vm_tag_jmpbuf_t; ++typedef rb_jmpbuf_t *rb_vm_tag_jmpbuf_t; + +-#define RB_VM_TAG_JMPBUF_GET(jmpbuf) ((jmpbuf)->buf) +-#else +-typedef rb_jmpbuf_t rb_vm_tag_jmpbuf_t; +- +-#define RB_VM_TAG_JMPBUF_GET(jmpbuf) (jmpbuf) +-#endif +- +-/* +- the members which are written in EC_PUSH_TAG() should be placed at +- the beginning and the end, so that entire region is accessible. +-*/ +-struct rb_vm_tag { +- VALUE tag; +- VALUE retval; +- rb_vm_tag_jmpbuf_t buf; +- struct rb_vm_tag *prev; +- enum ruby_tag_type state; +- unsigned int lock_rec; +-}; +- +-#if defined(__wasm__) && !defined(__EMSCRIPTEN__) +-static inline void +-_rb_vm_tag_jmpbuf_deinit_internal(rb_vm_tag_jmpbuf_t jmpbuf) +-{ +- rb_vm_tag_jmpbuf_t buf = jmpbuf; +- while (buf != NULL) { +- rb_vm_tag_jmpbuf_t next = buf->next; +- ruby_xfree(buf); +- buf = next; +- } +-} ++#define RB_VM_TAG_JMPBUF_GET(buf) (*buf) + + static inline void +-rb_vm_tag_jmpbuf_init(struct rb_vm_tag *tag) ++rb_vm_tag_jmpbuf_init(rb_vm_tag_jmpbuf_t *jmpbuf) + { +- if (tag->prev != NULL && tag->prev->buf->next != NULL) { +- _rb_vm_tag_jmpbuf_deinit_internal(tag->prev->buf->next); +- tag->prev->buf->next = NULL; +- } +- tag->buf = ruby_xmalloc(sizeof *tag->buf); +- tag->buf->next = NULL; +- if (tag->prev != NULL) { +- tag->prev->buf->next = tag->buf; +- } ++ *jmpbuf = ruby_xmalloc(sizeof(rb_jmpbuf_t)); + } + + static inline void +-rb_vm_tag_jmpbuf_deinit(struct rb_vm_tag *tag) ++rb_vm_tag_jmpbuf_deinit(const rb_vm_tag_jmpbuf_t *jmpbuf) + { +- if (tag->prev != NULL) { +- tag->prev->buf->next = NULL; +- } +- _rb_vm_tag_jmpbuf_deinit_internal(tag->buf); ++ ruby_xfree(*jmpbuf); + } + #else ++typedef rb_jmpbuf_t rb_vm_tag_jmpbuf_t; ++ ++#define RB_VM_TAG_JMPBUF_GET(buf) (buf) ++ + static inline void +-rb_vm_tag_jmpbuf_init(struct rb_vm_tag *tag) ++rb_vm_tag_jmpbuf_init(rb_vm_tag_jmpbuf_t *jmpbuf) + { + // no-op + } + + static inline void +-rb_vm_tag_jmpbuf_deinit(struct rb_vm_tag *tag) ++rb_vm_tag_jmpbuf_deinit(const rb_vm_tag_jmpbuf_t *jmpbuf) + { + // no-op + } + #endif + ++/* ++ the members which are written in EC_PUSH_TAG() should be placed at ++ the beginning and the end, so that entire region is accessible. ++*/ ++struct rb_vm_tag { ++ VALUE tag; ++ VALUE retval; ++ rb_vm_tag_jmpbuf_t buf; ++ struct rb_vm_tag *prev; ++ enum ruby_tag_type state; ++ unsigned int lock_rec; ++}; ++ + STATIC_ASSERT(rb_vm_tag_buf_offset, offsetof(struct rb_vm_tag, buf) > 0); + STATIC_ASSERT(rb_vm_tag_buf_end, + offsetof(struct rb_vm_tag, buf) + sizeof(rb_vm_tag_jmpbuf_t) < +-- +2.48.1 + diff --git a/patches/head/0003-Revert-Fix-stack-pointer-corruption-in-setjmp-handle.patch b/patches/head/0003-Revert-Fix-stack-pointer-corruption-in-setjmp-handle.patch new file mode 100644 index 000000000..836727674 --- /dev/null +++ b/patches/head/0003-Revert-Fix-stack-pointer-corruption-in-setjmp-handle.patch @@ -0,0 +1,63 @@ +From b0af5969522db7e78fd203ff3b8e3f4d7b4f43ea Mon Sep 17 00:00:00 2001 +From: Yuta Saito +Date: Tue, 1 Apr 2025 05:48:33 +0000 +Subject: [PATCH 3/3] Revert "Fix stack pointer corruption in setjmp handler in + WASI builds" + +This reverts commit 72fc9c7b1580251eac7d8db116df7f6e436be8b3. +--- + wasm/setjmp.c | 8 -------- + wasm/setjmp.h | 1 - + 2 files changed, 9 deletions(-) + +diff --git a/wasm/setjmp.c b/wasm/setjmp.c +index 32ede68c09..ebbf8949c1 100644 +--- a/wasm/setjmp.c ++++ b/wasm/setjmp.c +@@ -143,11 +143,9 @@ rb_wasm_try_catch_init(struct rb_wasm_try_catch *try_catch, + try_catch->try_f = try_f; + try_catch->catch_f = catch_f; + try_catch->context = context; +- try_catch->stack_pointer = NULL; + } + + // NOTE: This function is not processed by Asyncify due to a call of asyncify_stop_rewind +-__attribute__((noinline)) + void + rb_wasm_try_catch_loop_run(struct rb_wasm_try_catch *try_catch, rb_wasm_jmp_buf *target) + { +@@ -156,10 +154,6 @@ rb_wasm_try_catch_loop_run(struct rb_wasm_try_catch *try_catch, rb_wasm_jmp_buf + + target->state = JMP_BUF_STATE_CAPTURED; + +- if (try_catch->stack_pointer == NULL) { +- try_catch->stack_pointer = rb_wasm_get_stack_pointer(); +- } +- + switch ((enum try_catch_phase)try_catch->state) { + case TRY_CATCH_PHASE_MAIN: + // may unwind +@@ -181,8 +175,6 @@ rb_wasm_try_catch_loop_run(struct rb_wasm_try_catch *try_catch, rb_wasm_jmp_buf + // stop unwinding + // (but call stop_rewind to update the asyncify state to "normal" from "unwind") + asyncify_stop_rewind(); +- // reset the stack pointer to what it was before the most recent call to try_f or catch_f +- rb_wasm_set_stack_pointer(try_catch->stack_pointer); + // clear the active jmpbuf because it's already stopped + _rb_wasm_active_jmpbuf = NULL; + // reset jmpbuf state to be able to unwind again +diff --git a/wasm/setjmp.h b/wasm/setjmp.h +index e65bfc0ca0..cc14df33be 100644 +--- a/wasm/setjmp.h ++++ b/wasm/setjmp.h +@@ -65,7 +65,6 @@ struct rb_wasm_try_catch { + rb_wasm_try_catch_func_t try_f; + rb_wasm_try_catch_func_t catch_f; + void *context; +- void *stack_pointer; + int state; + }; + +-- +2.48.1 + From 9b73fa32b0be2091082f2041606604830db79e62 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Tue, 1 Apr 2025 06:22:28 +0000 Subject: [PATCH 2/6] Keep SJLJ leak fix applied --- ...buffer-leak-in-setjmp-handler-in-WAS.patch | 155 ------------------ 1 file changed, 155 deletions(-) delete mode 100644 patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch diff --git a/patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch b/patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch deleted file mode 100644 index c2688338b..000000000 --- a/patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 72a19c53d2ef1d3d452ad23fe3efc9e02de3a45c Mon Sep 17 00:00:00 2001 -From: Yuta Saito -Date: Tue, 1 Apr 2025 05:48:27 +0000 -Subject: [PATCH 2/3] Revert "Fix jump buffer leak in setjmp handler in WASI - builds" - -This reverts commit 3a730be8b464454878a42132f6fecb98ab4c1b5b. ---- - cont.c | 1 - - eval_intern.h | 4 +-- - vm_core.h | 77 +++++++++++++++++---------------------------------- - 3 files changed, 27 insertions(+), 55 deletions(-) - -diff --git a/cont.c b/cont.c -index ae68da4e83..072ae4562f 100644 ---- a/cont.c -+++ b/cont.c -@@ -1369,7 +1369,6 @@ cont_init(rb_context_t *cont, rb_thread_t *th) - /* save thread context */ - cont_save_thread(cont, th); - cont->saved_ec.thread_ptr = th; -- cont->saved_ec.tag = NULL; - cont->saved_ec.local_storage = NULL; - cont->saved_ec.local_storage_recursive_hash = Qnil; - cont->saved_ec.local_storage_recursive_hash_for_trace = Qnil; -diff --git a/eval_intern.h b/eval_intern.h -index 49229fa82d..ab0577e8ed 100644 ---- a/eval_intern.h -+++ b/eval_intern.h -@@ -102,11 +102,11 @@ extern int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval - _tag.tag = Qundef; \ - _tag.prev = _ec->tag; \ - _tag.lock_rec = rb_ec_vm_lock_rec(_ec); \ -- rb_vm_tag_jmpbuf_init(&_tag); -+ rb_vm_tag_jmpbuf_init(&_tag.buf); \ - - #define EC_POP_TAG() \ - _ec->tag = _tag.prev; \ -- rb_vm_tag_jmpbuf_deinit(&_tag); \ -+ rb_vm_tag_jmpbuf_deinit(&_tag.buf); \ - } while (0) - - #define EC_TMPPOP_TAG() \ -diff --git a/vm_core.h b/vm_core.h -index 28d742feed..d9159f5ccf 100644 ---- a/vm_core.h -+++ b/vm_core.h -@@ -946,79 +946,52 @@ typedef void *rb_jmpbuf_t[5]; - Therefore, we allocates the buffer on the heap on such - environments. - */ --typedef struct _rb_vm_tag_jmpbuf { -- struct _rb_vm_tag_jmpbuf *next; -- rb_jmpbuf_t buf; --} *rb_vm_tag_jmpbuf_t; -+typedef rb_jmpbuf_t *rb_vm_tag_jmpbuf_t; - --#define RB_VM_TAG_JMPBUF_GET(jmpbuf) ((jmpbuf)->buf) --#else --typedef rb_jmpbuf_t rb_vm_tag_jmpbuf_t; -- --#define RB_VM_TAG_JMPBUF_GET(jmpbuf) (jmpbuf) --#endif -- --/* -- the members which are written in EC_PUSH_TAG() should be placed at -- the beginning and the end, so that entire region is accessible. --*/ --struct rb_vm_tag { -- VALUE tag; -- VALUE retval; -- rb_vm_tag_jmpbuf_t buf; -- struct rb_vm_tag *prev; -- enum ruby_tag_type state; -- unsigned int lock_rec; --}; -- --#if defined(__wasm__) && !defined(__EMSCRIPTEN__) --static inline void --_rb_vm_tag_jmpbuf_deinit_internal(rb_vm_tag_jmpbuf_t jmpbuf) --{ -- rb_vm_tag_jmpbuf_t buf = jmpbuf; -- while (buf != NULL) { -- rb_vm_tag_jmpbuf_t next = buf->next; -- ruby_xfree(buf); -- buf = next; -- } --} -+#define RB_VM_TAG_JMPBUF_GET(buf) (*buf) - - static inline void --rb_vm_tag_jmpbuf_init(struct rb_vm_tag *tag) -+rb_vm_tag_jmpbuf_init(rb_vm_tag_jmpbuf_t *jmpbuf) - { -- if (tag->prev != NULL && tag->prev->buf->next != NULL) { -- _rb_vm_tag_jmpbuf_deinit_internal(tag->prev->buf->next); -- tag->prev->buf->next = NULL; -- } -- tag->buf = ruby_xmalloc(sizeof *tag->buf); -- tag->buf->next = NULL; -- if (tag->prev != NULL) { -- tag->prev->buf->next = tag->buf; -- } -+ *jmpbuf = ruby_xmalloc(sizeof(rb_jmpbuf_t)); - } - - static inline void --rb_vm_tag_jmpbuf_deinit(struct rb_vm_tag *tag) -+rb_vm_tag_jmpbuf_deinit(const rb_vm_tag_jmpbuf_t *jmpbuf) - { -- if (tag->prev != NULL) { -- tag->prev->buf->next = NULL; -- } -- _rb_vm_tag_jmpbuf_deinit_internal(tag->buf); -+ ruby_xfree(*jmpbuf); - } - #else -+typedef rb_jmpbuf_t rb_vm_tag_jmpbuf_t; -+ -+#define RB_VM_TAG_JMPBUF_GET(buf) (buf) -+ - static inline void --rb_vm_tag_jmpbuf_init(struct rb_vm_tag *tag) -+rb_vm_tag_jmpbuf_init(rb_vm_tag_jmpbuf_t *jmpbuf) - { - // no-op - } - - static inline void --rb_vm_tag_jmpbuf_deinit(struct rb_vm_tag *tag) -+rb_vm_tag_jmpbuf_deinit(const rb_vm_tag_jmpbuf_t *jmpbuf) - { - // no-op - } - #endif - -+/* -+ the members which are written in EC_PUSH_TAG() should be placed at -+ the beginning and the end, so that entire region is accessible. -+*/ -+struct rb_vm_tag { -+ VALUE tag; -+ VALUE retval; -+ rb_vm_tag_jmpbuf_t buf; -+ struct rb_vm_tag *prev; -+ enum ruby_tag_type state; -+ unsigned int lock_rec; -+}; -+ - STATIC_ASSERT(rb_vm_tag_buf_offset, offsetof(struct rb_vm_tag, buf) > 0); - STATIC_ASSERT(rb_vm_tag_buf_end, - offsetof(struct rb_vm_tag, buf) + sizeof(rb_vm_tag_jmpbuf_t) < --- -2.48.1 - From 2f416d5b633146259b416d8fd569b109a47c40ec Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Tue, 1 Apr 2025 06:54:13 +0000 Subject: [PATCH 3/6] Keep "Don't set `saved_ec.tag` to `NULL` in `cont_init()`" --- ...et-saved_ec.tag-to-NULL-in-cont_init.patch | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch diff --git a/patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch b/patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch deleted file mode 100644 index adf70c133..000000000 --- a/patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 3d186e7edd50ad4e8037f3cd017a19532a5f9a58 Mon Sep 17 00:00:00 2001 -From: Yuta Saito -Date: Tue, 1 Apr 2025 05:48:13 +0000 -Subject: [PATCH 1/3] Revert "Don't set `saved_ec.tag` to `NULL` in - `cont_init()`" - -This reverts commit 372515f33c908b36b3f5fbd2edcb34c69b418500. ---- - cont.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/cont.c b/cont.c -index 072ae4562f..ae68da4e83 100644 ---- a/cont.c -+++ b/cont.c -@@ -1369,6 +1369,7 @@ cont_init(rb_context_t *cont, rb_thread_t *th) - /* save thread context */ - cont_save_thread(cont, th); - cont->saved_ec.thread_ptr = th; -+ cont->saved_ec.tag = NULL; - cont->saved_ec.local_storage = NULL; - cont->saved_ec.local_storage_recursive_hash = Qnil; - cont->saved_ec.local_storage_recursive_hash_for_trace = Qnil; --- -2.48.1 - From 6e505df6895c20ff5e7ae42cbb42779ba5d5a82d Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Tue, 1 Apr 2025 07:24:11 +0000 Subject: [PATCH 4/6] Revert "Keep "Don't set `saved_ec.tag` to `NULL` in `cont_init()`"" This reverts commit 2f416d5b633146259b416d8fd569b109a47c40ec. --- ...et-saved_ec.tag-to-NULL-in-cont_init.patch | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch diff --git a/patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch b/patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch new file mode 100644 index 000000000..adf70c133 --- /dev/null +++ b/patches/head/0001-Revert-Don-t-set-saved_ec.tag-to-NULL-in-cont_init.patch @@ -0,0 +1,26 @@ +From 3d186e7edd50ad4e8037f3cd017a19532a5f9a58 Mon Sep 17 00:00:00 2001 +From: Yuta Saito +Date: Tue, 1 Apr 2025 05:48:13 +0000 +Subject: [PATCH 1/3] Revert "Don't set `saved_ec.tag` to `NULL` in + `cont_init()`" + +This reverts commit 372515f33c908b36b3f5fbd2edcb34c69b418500. +--- + cont.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/cont.c b/cont.c +index 072ae4562f..ae68da4e83 100644 +--- a/cont.c ++++ b/cont.c +@@ -1369,6 +1369,7 @@ cont_init(rb_context_t *cont, rb_thread_t *th) + /* save thread context */ + cont_save_thread(cont, th); + cont->saved_ec.thread_ptr = th; ++ cont->saved_ec.tag = NULL; + cont->saved_ec.local_storage = NULL; + cont->saved_ec.local_storage_recursive_hash = Qnil; + cont->saved_ec.local_storage_recursive_hash_for_trace = Qnil; +-- +2.48.1 + From 02ce7fb65bbb6ebd49e2a54c39c1c6962a46cffe Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Tue, 1 Apr 2025 07:24:20 +0000 Subject: [PATCH 5/6] Revert "Keep SJLJ leak fix applied" This reverts commit 9b73fa32b0be2091082f2041606604830db79e62. --- ...buffer-leak-in-setjmp-handler-in-WAS.patch | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch diff --git a/patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch b/patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch new file mode 100644 index 000000000..c2688338b --- /dev/null +++ b/patches/head/0002-Revert-Fix-jump-buffer-leak-in-setjmp-handler-in-WAS.patch @@ -0,0 +1,155 @@ +From 72a19c53d2ef1d3d452ad23fe3efc9e02de3a45c Mon Sep 17 00:00:00 2001 +From: Yuta Saito +Date: Tue, 1 Apr 2025 05:48:27 +0000 +Subject: [PATCH 2/3] Revert "Fix jump buffer leak in setjmp handler in WASI + builds" + +This reverts commit 3a730be8b464454878a42132f6fecb98ab4c1b5b. +--- + cont.c | 1 - + eval_intern.h | 4 +-- + vm_core.h | 77 +++++++++++++++++---------------------------------- + 3 files changed, 27 insertions(+), 55 deletions(-) + +diff --git a/cont.c b/cont.c +index ae68da4e83..072ae4562f 100644 +--- a/cont.c ++++ b/cont.c +@@ -1369,7 +1369,6 @@ cont_init(rb_context_t *cont, rb_thread_t *th) + /* save thread context */ + cont_save_thread(cont, th); + cont->saved_ec.thread_ptr = th; +- cont->saved_ec.tag = NULL; + cont->saved_ec.local_storage = NULL; + cont->saved_ec.local_storage_recursive_hash = Qnil; + cont->saved_ec.local_storage_recursive_hash_for_trace = Qnil; +diff --git a/eval_intern.h b/eval_intern.h +index 49229fa82d..ab0577e8ed 100644 +--- a/eval_intern.h ++++ b/eval_intern.h +@@ -102,11 +102,11 @@ extern int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval + _tag.tag = Qundef; \ + _tag.prev = _ec->tag; \ + _tag.lock_rec = rb_ec_vm_lock_rec(_ec); \ +- rb_vm_tag_jmpbuf_init(&_tag); ++ rb_vm_tag_jmpbuf_init(&_tag.buf); \ + + #define EC_POP_TAG() \ + _ec->tag = _tag.prev; \ +- rb_vm_tag_jmpbuf_deinit(&_tag); \ ++ rb_vm_tag_jmpbuf_deinit(&_tag.buf); \ + } while (0) + + #define EC_TMPPOP_TAG() \ +diff --git a/vm_core.h b/vm_core.h +index 28d742feed..d9159f5ccf 100644 +--- a/vm_core.h ++++ b/vm_core.h +@@ -946,79 +946,52 @@ typedef void *rb_jmpbuf_t[5]; + Therefore, we allocates the buffer on the heap on such + environments. + */ +-typedef struct _rb_vm_tag_jmpbuf { +- struct _rb_vm_tag_jmpbuf *next; +- rb_jmpbuf_t buf; +-} *rb_vm_tag_jmpbuf_t; ++typedef rb_jmpbuf_t *rb_vm_tag_jmpbuf_t; + +-#define RB_VM_TAG_JMPBUF_GET(jmpbuf) ((jmpbuf)->buf) +-#else +-typedef rb_jmpbuf_t rb_vm_tag_jmpbuf_t; +- +-#define RB_VM_TAG_JMPBUF_GET(jmpbuf) (jmpbuf) +-#endif +- +-/* +- the members which are written in EC_PUSH_TAG() should be placed at +- the beginning and the end, so that entire region is accessible. +-*/ +-struct rb_vm_tag { +- VALUE tag; +- VALUE retval; +- rb_vm_tag_jmpbuf_t buf; +- struct rb_vm_tag *prev; +- enum ruby_tag_type state; +- unsigned int lock_rec; +-}; +- +-#if defined(__wasm__) && !defined(__EMSCRIPTEN__) +-static inline void +-_rb_vm_tag_jmpbuf_deinit_internal(rb_vm_tag_jmpbuf_t jmpbuf) +-{ +- rb_vm_tag_jmpbuf_t buf = jmpbuf; +- while (buf != NULL) { +- rb_vm_tag_jmpbuf_t next = buf->next; +- ruby_xfree(buf); +- buf = next; +- } +-} ++#define RB_VM_TAG_JMPBUF_GET(buf) (*buf) + + static inline void +-rb_vm_tag_jmpbuf_init(struct rb_vm_tag *tag) ++rb_vm_tag_jmpbuf_init(rb_vm_tag_jmpbuf_t *jmpbuf) + { +- if (tag->prev != NULL && tag->prev->buf->next != NULL) { +- _rb_vm_tag_jmpbuf_deinit_internal(tag->prev->buf->next); +- tag->prev->buf->next = NULL; +- } +- tag->buf = ruby_xmalloc(sizeof *tag->buf); +- tag->buf->next = NULL; +- if (tag->prev != NULL) { +- tag->prev->buf->next = tag->buf; +- } ++ *jmpbuf = ruby_xmalloc(sizeof(rb_jmpbuf_t)); + } + + static inline void +-rb_vm_tag_jmpbuf_deinit(struct rb_vm_tag *tag) ++rb_vm_tag_jmpbuf_deinit(const rb_vm_tag_jmpbuf_t *jmpbuf) + { +- if (tag->prev != NULL) { +- tag->prev->buf->next = NULL; +- } +- _rb_vm_tag_jmpbuf_deinit_internal(tag->buf); ++ ruby_xfree(*jmpbuf); + } + #else ++typedef rb_jmpbuf_t rb_vm_tag_jmpbuf_t; ++ ++#define RB_VM_TAG_JMPBUF_GET(buf) (buf) ++ + static inline void +-rb_vm_tag_jmpbuf_init(struct rb_vm_tag *tag) ++rb_vm_tag_jmpbuf_init(rb_vm_tag_jmpbuf_t *jmpbuf) + { + // no-op + } + + static inline void +-rb_vm_tag_jmpbuf_deinit(struct rb_vm_tag *tag) ++rb_vm_tag_jmpbuf_deinit(const rb_vm_tag_jmpbuf_t *jmpbuf) + { + // no-op + } + #endif + ++/* ++ the members which are written in EC_PUSH_TAG() should be placed at ++ the beginning and the end, so that entire region is accessible. ++*/ ++struct rb_vm_tag { ++ VALUE tag; ++ VALUE retval; ++ rb_vm_tag_jmpbuf_t buf; ++ struct rb_vm_tag *prev; ++ enum ruby_tag_type state; ++ unsigned int lock_rec; ++}; ++ + STATIC_ASSERT(rb_vm_tag_buf_offset, offsetof(struct rb_vm_tag, buf) > 0); + STATIC_ASSERT(rb_vm_tag_buf_end, + offsetof(struct rb_vm_tag, buf) + sizeof(rb_vm_tag_jmpbuf_t) < +-- +2.48.1 + From 4637b7cf6679a5e17cf61901c6fedc29c16740ab Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Tue, 1 Apr 2025 07:24:56 +0000 Subject: [PATCH 6/6] Keep stack pointer corruption fix --- ...-pointer-corruption-in-setjmp-handle.patch | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 patches/head/0003-Revert-Fix-stack-pointer-corruption-in-setjmp-handle.patch diff --git a/patches/head/0003-Revert-Fix-stack-pointer-corruption-in-setjmp-handle.patch b/patches/head/0003-Revert-Fix-stack-pointer-corruption-in-setjmp-handle.patch deleted file mode 100644 index 836727674..000000000 --- a/patches/head/0003-Revert-Fix-stack-pointer-corruption-in-setjmp-handle.patch +++ /dev/null @@ -1,63 +0,0 @@ -From b0af5969522db7e78fd203ff3b8e3f4d7b4f43ea Mon Sep 17 00:00:00 2001 -From: Yuta Saito -Date: Tue, 1 Apr 2025 05:48:33 +0000 -Subject: [PATCH 3/3] Revert "Fix stack pointer corruption in setjmp handler in - WASI builds" - -This reverts commit 72fc9c7b1580251eac7d8db116df7f6e436be8b3. ---- - wasm/setjmp.c | 8 -------- - wasm/setjmp.h | 1 - - 2 files changed, 9 deletions(-) - -diff --git a/wasm/setjmp.c b/wasm/setjmp.c -index 32ede68c09..ebbf8949c1 100644 ---- a/wasm/setjmp.c -+++ b/wasm/setjmp.c -@@ -143,11 +143,9 @@ rb_wasm_try_catch_init(struct rb_wasm_try_catch *try_catch, - try_catch->try_f = try_f; - try_catch->catch_f = catch_f; - try_catch->context = context; -- try_catch->stack_pointer = NULL; - } - - // NOTE: This function is not processed by Asyncify due to a call of asyncify_stop_rewind --__attribute__((noinline)) - void - rb_wasm_try_catch_loop_run(struct rb_wasm_try_catch *try_catch, rb_wasm_jmp_buf *target) - { -@@ -156,10 +154,6 @@ rb_wasm_try_catch_loop_run(struct rb_wasm_try_catch *try_catch, rb_wasm_jmp_buf - - target->state = JMP_BUF_STATE_CAPTURED; - -- if (try_catch->stack_pointer == NULL) { -- try_catch->stack_pointer = rb_wasm_get_stack_pointer(); -- } -- - switch ((enum try_catch_phase)try_catch->state) { - case TRY_CATCH_PHASE_MAIN: - // may unwind -@@ -181,8 +175,6 @@ rb_wasm_try_catch_loop_run(struct rb_wasm_try_catch *try_catch, rb_wasm_jmp_buf - // stop unwinding - // (but call stop_rewind to update the asyncify state to "normal" from "unwind") - asyncify_stop_rewind(); -- // reset the stack pointer to what it was before the most recent call to try_f or catch_f -- rb_wasm_set_stack_pointer(try_catch->stack_pointer); - // clear the active jmpbuf because it's already stopped - _rb_wasm_active_jmpbuf = NULL; - // reset jmpbuf state to be able to unwind again -diff --git a/wasm/setjmp.h b/wasm/setjmp.h -index e65bfc0ca0..cc14df33be 100644 ---- a/wasm/setjmp.h -+++ b/wasm/setjmp.h -@@ -65,7 +65,6 @@ struct rb_wasm_try_catch { - rb_wasm_try_catch_func_t try_f; - rb_wasm_try_catch_func_t catch_f; - void *context; -- void *stack_pointer; - int state; - }; - --- -2.48.1 -