From 7c28c9b13f7c924c18920b51f42b1119c3b1e2ee Mon Sep 17 00:00:00 2001 From: grischka Date: Fri, 11 Nov 2016 18:29:45 +0100 Subject: [PATCH] tccgen: inline_functions double free fix Fix double free of the inline function token_string which could happen when an error/longjmp occurred while compiling the inline function. --- tcc.h | 2 +- tccgen.c | 16 +++++++++------- tccpp.c | 3 +-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/tcc.h b/tcc.h index e536f6c..18e049e 100644 --- a/tcc.h +++ b/tcc.h @@ -532,7 +532,7 @@ typedef struct TokenString { /* inline functions */ typedef struct InlineFunc { - TokenString func_str; + TokenString *func_str; Sym *sym; char filename[1]; } InlineFunc; diff --git a/tccgen.c b/tccgen.c index 73371c0..427649b 100644 --- a/tccgen.c +++ b/tccgen.c @@ -6523,7 +6523,7 @@ static void gen_inline_functions(TCCState *s) sym->r = VT_SYM | VT_CONST; sym->type.t &= ~VT_INLINE; - begin_macro(&fn->func_str, 0); + begin_macro(fn->func_str, 1); next(); cur_text_section = text_section; gen_function(sym); @@ -6544,8 +6544,10 @@ ST_FUNC void free_inline_functions(TCCState *s) /* free tokens of unused inline functions */ for (i = 0; i < s->nb_inline_fns; ++i) { struct InlineFunc *fn = s->inline_fns[i]; - if (fn->sym) - tok_str_free(fn->func_str.str); + if (fn->sym) { + tok_str_free(fn->func_str->str); + tal_free(tokstr_alloc, fn->func_str); + } } dynarray_reset(&s->inline_fns, &s->nb_inline_fns); } @@ -6701,14 +6703,14 @@ static int decl0(int l, int is_for_loop_init) fn = tcc_malloc(sizeof *fn + strlen(filename)); strcpy(fn->filename, filename); fn->sym = sym; - tok_str_new(&fn->func_str); + fn->func_str = tok_str_alloc(); block_level = 0; for(;;) { int t; if (tok == TOK_EOF) tcc_error("unexpected end of file"); - tok_str_add_tok(&fn->func_str); + tok_str_add_tok(fn->func_str); t = tok; next(); if (t == '{') { @@ -6719,8 +6721,8 @@ static int decl0(int l, int is_for_loop_init) break; } } - tok_str_add(&fn->func_str, -1); - tok_str_add(&fn->func_str, 0); + tok_str_add(fn->func_str, -1); + tok_str_add(fn->func_str, 0); dynarray_add((void ***)&tcc_state->inline_fns, &tcc_state->nb_inline_fns, fn); } else { diff --git a/tccpp.c b/tccpp.c index b75603f..0bfeaeb 100644 --- a/tccpp.c +++ b/tccpp.c @@ -1124,8 +1124,7 @@ ST_FUNC void end_macro(void) str->alloc = 3; /* just mark as finished */ } else { tok_str_free(str->str); - if (str->alloc == 1) - tal_free(tokstr_alloc, str); + tal_free(tokstr_alloc, str); } }