From 8d31d2526bb6e37d5e6f91381482074d94957b01 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Mon, 12 Oct 2015 11:21:55 -0500 Subject: [PATCH 1/3] config.c: Fix #include after [section](+). An #include right after a [section](+) would associate any variable assignments before a new section in the #include with the wrong section. * Fix section association by setting the current section to the appended section. * Fix '+' and '!' section flag interaction corner case depending upon which flag came first. If the '!' came first then it would be ignored. If the '!' came after then it would affect the appended section. The '!' will now no longer be ignored. ASTERISK-25461 #close Reported by: Sean Pimental Change-Id: Ic9d3191c8758048e2cbce6432f854b32531731c3 --- main/config.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main/config.c b/main/config.c index 7484b66ba4..fd03c906f2 100644 --- a/main/config.c +++ b/main/config.c @@ -1696,6 +1696,8 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, return -1; } if (newcat) { + ast_config_set_current_category(cfg, *cat); + (*cat)->ignored |= newcat->ignored; move_variables(newcat, *cat); ast_category_destroy(newcat); newcat = NULL; From a99e821520405be48241f2a51c659cefd6939da2 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Mon, 12 Oct 2015 11:20:29 -0500 Subject: [PATCH 2/3] config.c: Fix potential memory corruption after [section](+). The memory corruption could happen if the [section](+) is the last section in the file with trailing comments. In this case process_text_line() has left *last_cat is set to newcat and newcat is destroyed. Change-Id: I0d1d999f553986f591becd000e7cc6ddfb978d93 --- main/config.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/main/config.c b/main/config.c index fd03c906f2..1778494412 100644 --- a/main/config.c +++ b/main/config.c @@ -1647,7 +1647,7 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, * You can put a comma-separated list of categories and templates * and '!' and '+' between parentheses, with obvious meaning. */ - struct ast_category *newcat = NULL; + struct ast_category *newcat; char *catname; c = strchr(cur, ']'); @@ -1660,14 +1660,13 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, if (*c++ != '(') c = NULL; catname = cur; - if (!(*cat = newcat = ast_category_new(catname, - S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile), - lineno))) { + *cat = newcat = ast_category_new(catname, + S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile), + lineno); + if (!newcat) { return -1; } (*cat)->lineno = lineno; - *last_var = 0; - *last_cat = newcat; /* add comments */ if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) @@ -1690,8 +1689,9 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, } else if (!strcasecmp(cur, "+")) { *cat = ast_category_get(cfg, catname, NULL); if (!(*cat)) { - if (newcat) + if (newcat) { ast_category_destroy(newcat); + } ast_log(LOG_WARNING, "Category addition requested, but category '%s' does not exist, line %d of %s\n", catname, lineno, configfile); return -1; } @@ -1717,8 +1717,19 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, } } } - if (newcat) - ast_category_append(cfg, *cat); + + /* + * We need to set *last_cat to newcat here regardless. If the + * category is being appended to we have no place for trailing + * comments on the appended category. The appended category + * may be in another file or it already has trailing comments + * that we would then leak. + */ + *last_var = NULL; + *last_cat = newcat; + if (newcat) { + ast_category_append(cfg, newcat); + } } else if (cur[0] == '#') { /* A directive - #include or #exec */ char *cur2; char real_inclusion_name[256]; @@ -1874,7 +1885,7 @@ set_new_variable: } else if ((v = ast_variable_new(cur, ast_strip(c), S_OR(suggested_include_file, cfg->include_level == 1 ? "" : configfile)))) { v->lineno = lineno; v->object = object; - *last_cat = 0; + *last_cat = NULL; *last_var = v; /* Put and reset comments */ v->blanklines = 0; @@ -1914,8 +1925,8 @@ static struct ast_config *config_text_file_load(const char *database, const char struct stat statbuf; struct cache_file_mtime *cfmtime = NULL; struct cache_file_include *cfinclude; - struct ast_variable *last_var = 0; - struct ast_category *last_cat = 0; + struct ast_variable *last_var = NULL; + struct ast_category *last_cat = NULL; /*! Growable string buffer */ struct ast_str *comment_buffer = NULL; /*!< this will be a comment collector.*/ struct ast_str *lline_buffer = NULL; /*!< A buffer for stuff behind the ; */ From e14023ca3543d91bc108f8f21af0509c2a428e47 Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Mon, 12 Oct 2015 11:21:39 -0500 Subject: [PATCH 3/3] config.c: Fix off-nominal memory leak. Change-Id: I06e346e9a5c63cc5071e7eda537310c4b43bffe0 --- main/config.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/main/config.c b/main/config.c index 1778494412..eefc8ca3b6 100644 --- a/main/config.c +++ b/main/config.c @@ -1679,6 +1679,7 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, /* If there are options or categories to inherit from, process them now */ if (c) { if (!(cur = strchr(c, ')'))) { + ast_category_destroy(newcat); ast_log(LOG_WARNING, "parse error: no closing ')', line %d of %s\n", lineno, configfile); return -1; } @@ -1707,10 +1708,16 @@ static int process_text_line(struct ast_config *cfg, struct ast_category **cat, base = ast_category_get(cfg, cur, "TEMPLATES=include"); if (!base) { + if (newcat) { + ast_category_destroy(newcat); + } ast_log(LOG_WARNING, "Inheritance requested, but category '%s' does not exist, line %d of %s\n", cur, lineno, configfile); return -1; } if (ast_category_inherit(*cat, base)) { + if (newcat) { + ast_category_destroy(newcat); + } ast_log(LOG_ERROR, "Inheritence requested, but allocation failed\n"); return -1; }