From c1ed11ee313af9f099049fc4c99bda989c93d3ff 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 008abffdf5..5fe73b7a0f 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 9951255775a28e28632c1ec7f4b24e021d3b59c6 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 5fe73b7a0f..25bc013ddd 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 984f100dab92fe4051148498e5fab917fe5f4f40 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 25bc013ddd..98fa9a2926 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; }