mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	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:
		| @@ -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 */ | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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( | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose