Fix memory leak and use after free

Use after free was caused by missing janet_gcroot call when
setting up thread.
This commit is contained in:
Calvin Rose 2021-08-19 21:51:53 -05:00
parent cc066dd6a1
commit c8827424e7
3 changed files with 19 additions and 4 deletions

View File

@ -2487,6 +2487,7 @@ static JanetEVGenericMessage janet_go_thread_subr(JanetEVGenericMessage args) {
JANET_MARSHAL_UNSAFE, NULL, &nextbytes);
if (!janet_checktype(aregv, JANET_TABLE)) janet_panic("expected table for abstract registry");
janet_vm.abstract_registry = janet_unwrap_table(aregv);
janet_gcroot(janet_wrap_table(janet_vm.abstract_registry));
}
/* Get supervsior */

View File

@ -512,6 +512,21 @@ int janet_gcunrootall(Janet root) {
/* Free all allocated memory */
void janet_clear_memory(void) {
#ifdef JANET_EV
JanetKV *items = janet_vm.threaded_abstracts.data;
for (int32_t i = 0; i < janet_vm.threaded_abstracts.capacity; i++) {
if (janet_checktype(items[i].key, JANET_ABSTRACT)) {
void *abst = janet_unwrap_abstract(items[i].key);
if (0 == janet_abstract_decref(abst)) {
JanetAbstractHead *head = janet_abstract_head(abst);
if (head->type->gc) {
janet_assert(!head->type->gc(head->data, head->size), "finalizer failed");
}
janet_free(janet_abstract_head(abst));
}
}
}
#endif
JanetGCObject *current = janet_vm.blocks;
while (NULL != current) {
janet_deinit_block(current);

View File

@ -1143,17 +1143,16 @@ static const uint8_t *unmarshal_one_abstract(UnmarshalState *st, const uint8_t *
Janet key;
data = unmarshal_one(st, data, &key, flags + 1);
const JanetAbstractType *at = janet_get_abstract_type(key);
if (at == NULL) goto oops;
if (at == NULL) janet_panic("unknown abstract type");
if (at->unmarshal) {
JanetMarshalContext context = {NULL, st, flags, data, at};
*out = janet_wrap_abstract(at->unmarshal(&context));
if (context.at != NULL) {
janet_panicf("janet_unmarshal_abstract not called");
janet_panic("janet_unmarshal_abstract not called");
}
return context.data;
}
oops:
janet_panic("invalid abstract type");
janet_panic("invalid abstract type - no unmarshal function pointer");
}
static const uint8_t *unmarshal_one(