]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
config: bug: Fix SEGV in ast_category_insert when matching category isn't found
authorGeorge Joseph <george.joseph@fairview5.com>
Thu, 18 Sep 2014 14:37:08 +0000 (14:37 +0000)
committerGeorge Joseph <george.joseph@fairview5.com>
Thu, 18 Sep 2014 14:37:08 +0000 (14:37 +0000)
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/

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@423276 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/config.h
main/config.c
main/manager.c

index 3079666981d4add2f0193849d7827ca216770200..e7f2c4ee8a3fdc660c2cba232e5a1202ae238969 100644 (file)
@@ -554,8 +554,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);
 
 /*!
index ac46f4b0c3a98ecc010de102af3622ded6142d5f..b86f38d8a620f282dc92ffa971297d5a43a2fddc 100644 (file)
@@ -727,24 +727,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;
-       } 
-       for (cur_category = config->root; cur_category; cur_category = cur_category->next) {
+               return 0;
+       }
+       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)
index f65a159e6175a809c311d34fdac80d56a97dfd2a..5ed5e8535aa1606d86f2608144f5facee2d7ebc1 100644 (file)
@@ -2747,7 +2747,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)) {