From 71c8a9513b43e30358a3c5f0448a768d908852f2 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Tue, 29 Jan 2019 20:09:35 +0200 Subject: Fixes in runtime memory management * src/builtin/sprintf.bi: Don't use pointer to format: the latter might be reallocated during stack expansions, and the pointer would end up pointing to freed memory area. Another way to fix it would be to make env_register_auto and env_pop_auto global and to mark the address of pointer with env_register_auto so it would be reallocated together with format. However, I wouldn't like to expose too much of the internals of prog.c. * src/prog.c (env_get_locus) (heap_obstack_grow,pushs): Fix argument to env_register_auto. (env_register_auto): Check if the argument points to a memory location within data segment + stack. This is necessary, because heap_obstack_grow registers its argument, which at least in one case is a pointer to an automatic variable (see MF_OBSTACK_1GROW in builtin/snarf.m4). (env_pop_auto,env_unregister_autos) (env_fixup_autos): Make static. --- src/prog.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src/prog.c') diff --git a/src/prog.c b/src/prog.c index 83401ef3..75b52284 100644 --- a/src/prog.c +++ b/src/prog.c @@ -384,7 +384,7 @@ env_get_locus(eval_environ_t env, struct mu_locus_range *locus) { mu_locus_range_init(locus); locus->beg.mu_file = (char*)(env->dataseg + env->locus.file); - env_register_auto(env, (void*) locus->beg.mu_file); + env_register_auto(env, (void*) &locus->beg.mu_file); locus->beg.mu_line = env->locus.line; #if 0 locus->beg.mu_col = env->locus.point; @@ -493,32 +493,39 @@ env_function_cleanup_add(eval_environ_t env, void *data, static void env_register_auto(eval_environ_t env, void *ptr) { + char *addr = *(char**)ptr; + if (env->numautos == MAX_AUTO_PTR) runtime_error(env, "INTERNAL ERROR at %s:%d, please report", __FILE__, __LINE__); + /* Check if address is within the dataseg */ + if (!(addr >= (char*) env->dataseg + && (addr < (char*) (env->dataseg + datasize + env->stack_size)))) + ptr = NULL; env->auto_ptr[env->numautos++] = ptr; } /* Pop the last registered auto variable */ -void +static void env_pop_auto(eval_environ_t env) { env->numautos--; } -void +static void env_unregister_autos(eval_environ_t env) { env->numautos = 0; } -void +static void env_fixup_autos(eval_environ_t env, ptrdiff_t offset) { int i; for (i = 0; i < env->numautos; i++) { STKVAL *pptr = env->auto_ptr[i]; - mf_c_val(*pptr,str) += offset; /*FIXME*/ + if (pptr) + mf_c_val(*pptr,str) += offset; /*FIXME*/ } } @@ -799,7 +806,7 @@ heap_obstack_grow(eval_environ_t env, void * MFL_DATASEG ptr, size_t size) size_t words = B2STACK(size); char *ret; - env_register_auto(env, ptr); + env_register_auto(env, (void*) &ptr); if (env->tos - env->toh < words + B2STACK(env->temp_size)) expand_dataseg(env, words, _("memory chunk too big to fit into heap")); @@ -829,7 +836,7 @@ pushs(eval_environ_t env, const char * MFL_DATASEG s) { size_t off; - env_register_auto(env, (void*) s); + env_register_auto(env, (void*) &s); off = heap_reserve(env, strlen(s) + 1); strcpy((char*) env_data_ref(env, off), s); env_pop_auto(env); -- cgit v1.2.1