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 */
|
/* save thread context */
|
||||||
cont_save_thread(cont, th);
|
cont_save_thread(cont, th);
|
||||||
cont->saved_ec.thread_ptr = th;
|
cont->saved_ec.thread_ptr = th;
|
||||||
|
cont->saved_ec.tag = NULL;
|
||||||
cont->saved_ec.local_storage = NULL;
|
cont->saved_ec.local_storage = NULL;
|
||||||
cont->saved_ec.local_storage_recursive_hash = Qnil;
|
cont->saved_ec.local_storage_recursive_hash = Qnil;
|
||||||
cont->saved_ec.local_storage_recursive_hash_for_trace = 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.tag = Qundef; \
|
||||||
_tag.prev = _ec->tag; \
|
_tag.prev = _ec->tag; \
|
||||||
_tag.lock_rec = rb_ec_vm_lock_rec(_ec); \
|
_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() \
|
#define EC_POP_TAG() \
|
||||||
_ec->tag = _tag.prev; \
|
_ec->tag = _tag.prev; \
|
||||||
rb_vm_tag_jmpbuf_deinit(&_tag.buf); \
|
rb_vm_tag_jmpbuf_deinit(&_tag); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define EC_TMPPOP_TAG() \
|
#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
|
Therefore, we allocates the buffer on the heap on such
|
||||||
environments.
|
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)
|
#define RB_VM_TAG_JMPBUF_GET(jmpbuf) ((jmpbuf)->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);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
typedef rb_jmpbuf_t rb_vm_tag_jmpbuf_t;
|
typedef rb_jmpbuf_t rb_vm_tag_jmpbuf_t;
|
||||||
|
|
||||||
#define RB_VM_TAG_JMPBUF_GET(buf) (buf)
|
#define RB_VM_TAG_JMPBUF_GET(jmpbuf) (jmpbuf)
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -992,6 +971,54 @@ struct rb_vm_tag {
|
|||||||
unsigned int lock_rec;
|
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_offset, offsetof(struct rb_vm_tag, buf) > 0);
|
||||||
STATIC_ASSERT(rb_vm_tag_buf_end,
|
STATIC_ASSERT(rb_vm_tag_buf_end,
|
||||||
offsetof(struct rb_vm_tag, buf) + sizeof(rb_vm_tag_jmpbuf_t) <
|
offsetof(struct rb_vm_tag, buf) + sizeof(rb_vm_tag_jmpbuf_t) <
|
||||||
|
Loading…
x
Reference in New Issue
Block a user