Fix jump buffer leak in setjmp handler in WASI builds
This commit is contained in:
parent
72fc9c7b15
commit
3a730be8b4
Notes:
git
2025-03-31 02:59:51 +00:00
1
cont.c
1
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;
|
||||
|
@ -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.buf); \
|
||||
rb_vm_tag_jmpbuf_init(&_tag);
|
||||
|
||||
#define EC_POP_TAG() \
|
||||
_ec->tag = _tag.prev; \
|
||||
rb_vm_tag_jmpbuf_deinit(&_tag.buf); \
|
||||
rb_vm_tag_jmpbuf_deinit(&_tag); \
|
||||
} while (0)
|
||||
|
||||
#define EC_TMPPOP_TAG() \
|
||||
|
81
vm_core.h
81
vm_core.h
@ -946,37 +946,16 @@ typedef void *rb_jmpbuf_t[5];
|
||||
Therefore, we allocates the buffer on the heap on such
|
||||
environments.
|
||||
*/
|
||||
typedef rb_jmpbuf_t *rb_vm_tag_jmpbuf_t;
|
||||
typedef struct _rb_vm_tag_jmpbuf {
|
||||
struct _rb_vm_tag_jmpbuf *next;
|
||||
rb_jmpbuf_t buf;
|
||||
} *rb_vm_tag_jmpbuf_t;
|
||||
|
||||
#define RB_VM_TAG_JMPBUF_GET(buf) (*buf)
|
||||
|
||||
static inline void
|
||||
rb_vm_tag_jmpbuf_init(rb_vm_tag_jmpbuf_t *jmpbuf)
|
||||
{
|
||||
*jmpbuf = ruby_xmalloc(sizeof(rb_jmpbuf_t));
|
||||
}
|
||||
|
||||
static inline void
|
||||
rb_vm_tag_jmpbuf_deinit(const rb_vm_tag_jmpbuf_t *jmpbuf)
|
||||
{
|
||||
ruby_xfree(*jmpbuf);
|
||||
}
|
||||
#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(buf) (buf)
|
||||
|
||||
static inline void
|
||||
rb_vm_tag_jmpbuf_init(rb_vm_tag_jmpbuf_t *jmpbuf)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
static inline void
|
||||
rb_vm_tag_jmpbuf_deinit(const rb_vm_tag_jmpbuf_t *jmpbuf)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
#define RB_VM_TAG_JMPBUF_GET(jmpbuf) (jmpbuf)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -992,6 +971,54 @@ struct rb_vm_tag {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
rb_vm_tag_jmpbuf_init(struct rb_vm_tag *tag)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
rb_vm_tag_jmpbuf_deinit(struct rb_vm_tag *tag)
|
||||
{
|
||||
if (tag->prev != NULL) {
|
||||
tag->prev->buf->next = NULL;
|
||||
}
|
||||
_rb_vm_tag_jmpbuf_deinit_internal(tag->buf);
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
rb_vm_tag_jmpbuf_init(struct rb_vm_tag *tag)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
static inline void
|
||||
rb_vm_tag_jmpbuf_deinit(struct rb_vm_tag *tag)
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
#endif
|
||||
|
||||
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) <
|
||||
|
Loading…
x
Reference in New Issue
Block a user