summaryrefslogtreecommitdiffabout
path: root/src/prog.c
authorSergey Poznyakoff <gray@gnu.org>2019-01-29 18:09:35 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2019-01-29 18:09:35 (GMT)
commit71c8a9513b43e30358a3c5f0448a768d908852f2 (patch) (side-by-side diff)
treeca723fbefd708e691d55567f593075ac0d9ed62c /src/prog.c
parent84800d74f3c2855fe80d1bc5060923cdb9046551 (diff)
downloadmailfromd-71c8a9513b43e30358a3c5f0448a768d908852f2.tar.gz
mailfromd-71c8a9513b43e30358a3c5f0448a768d908852f2.tar.bz2
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.
Diffstat (limited to 'src/prog.c') (more/less context) (ignore whitespace changes)
-rw-r--r--src/prog.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/src/prog.c b/src/prog.c
index 83401ef..75b5228 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);

Return to:

Send suggestions and report system problems to the System administrator.