From d120e403092d058dfdb7655ba8e1b8113d3b8a33 Mon Sep 17 00:00:00 2001 From: George Joseph Date: Thu, 18 Sep 2014 14:46:12 +0000 Subject: [PATCH] config: bug: Fix SEGV in ast_category_insert when matching category isn't found If you call ast_category_insert with a match category that doesn't exist, the list traverse runs out of 'next' categories and you get a SEGV. This patch adds check for the end-of-list condition and changes the signature to return an int for success/failure indication instead of a void. The only consumer of this function is manager and it was also changed to use the return value. Tested by: George Joseph Review: https://reviewboard.asterisk.org/r/3993/ ........ Merged revisions 423276 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 423277 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 423278 from http://svn.asterisk.org/svn/asterisk/branches/12 ........ Merged revisions 423279 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@423280 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- include/asterisk/config.h | 5 ++++- main/config.c | 16 ++++++++++------ main/manager.c | 6 +++++- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/asterisk/config.h b/include/asterisk/config.h index 2579ef2795..541fea4ff7 100644 --- a/include/asterisk/config.h +++ b/include/asterisk/config.h @@ -675,8 +675,11 @@ void ast_category_append(struct ast_config *config, struct ast_category *cat); * \details * This function is used to insert a new category above another category * matching the match parameter. + * + * \retval 0 if succeeded + * \retval -1 if NULL parameters or match category was not found */ -void ast_category_insert(struct ast_config *config, struct ast_category *cat, const char *match); +int ast_category_insert(struct ast_config *config, struct ast_category *cat, const char *match); int ast_category_delete(struct ast_config *cfg, const char *category); /*! diff --git a/main/config.c b/main/config.c index 622d6ed764..55c40a9555 100644 --- a/main/config.c +++ b/main/config.c @@ -783,24 +783,28 @@ void ast_category_append(struct ast_config *config, struct ast_category *categor config->current = category; } -void ast_category_insert(struct ast_config *config, struct ast_category *cat, const char *match) +int ast_category_insert(struct ast_config *config, struct ast_category *cat, const char *match) { struct ast_category *cur_category; - if (!cat || !match) - return; + if (!config || !cat || !match) { + return -1; + } if (!strcasecmp(config->root->name, match)) { cat->next = config->root; config->root = cat; - return; + return 0; } - for (cur_category = config->root; cur_category; cur_category = cur_category->next) { + for (cur_category = config->root; cur_category && cur_category->next; + cur_category = cur_category->next) { if (!strcasecmp(cur_category->next->name, match)) { cat->next = cur_category->next; cur_category->next = cat; - break; + return 0; } } + + return -1; } static void ast_destroy_template_list(struct ast_category *cat) diff --git a/main/manager.c b/main/manager.c index 6545a519e2..9744ab6140 100644 --- a/main/manager.c +++ b/main/manager.c @@ -3321,7 +3321,11 @@ static enum error_type handle_updates(struct mansession *s, const struct message if (ast_strlen_zero(match)) { ast_category_append(cfg, category); } else { - ast_category_insert(cfg, category, match); + if (ast_category_insert(cfg, category, match)) { + result = FAILURE_NEWCAT; + ast_category_destroy(category); + break; + } } } else if (!strcasecmp(action, "renamecat")) { if (ast_strlen_zero(value)) {