]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
pbx.c: Prevent infinite recursion in manager_show_dialplan_helper. 54/3754/1
authorEtienne Lessard <elessard@proformatique.com>
Mon, 29 Aug 2016 12:11:47 +0000 (08:11 -0400)
committerEtienne Lessard <elessard@proformatique.com>
Mon, 29 Aug 2016 12:13:43 +0000 (08:13 -0400)
Previously, if context A was including context B and context B was including
context A, i.e. if there was a circular dependency between contexts, then
calling manager_show_dialplan_helper could lead to an infinite recursion,
resulting in a crash.

This commit applies the same solution as the one implemented in the
show_dialplan_helper function. The manager_show_dialplan_helper and
show_dialplan_helper functions contain lots of code in common, but the former
was missing the "infinite recursion avoidance" code.

ASTERISK-26226 #close

Change-Id: I1aea85133c21787226f4f8442253a93000aa0897

main/pbx.c

index daf2e437c59de28327bb3d5a9a5cdeb0ce05e815..684df5347ed80c7fd5e13ea0bd87bb7de82aaa2d 100644 (file)
@@ -8472,7 +8472,8 @@ static void manager_dpsendack(struct mansession *s, const struct message *m)
 static int manager_show_dialplan_helper(struct mansession *s, const struct message *m,
                                        const char *actionidtext, const char *context,
                                        const char *exten, struct dialplan_counters *dpc,
-                                       struct ast_include *rinclude)
+                                       struct ast_include *rinclude,
+                                       int includecount, const char *includes[])
 {
        struct ast_context *c;
        int res = 0, old_total_exten = dpc->total_exten;
@@ -8554,7 +8555,24 @@ static int manager_show_dialplan_helper(struct mansession *s, const struct messa
                while ( (i = ast_walk_context_includes(c, i)) ) {
                        if (exten) {
                                /* Check all includes for the requested extension */
-                               manager_show_dialplan_helper(s, m, actionidtext, ast_get_include_name(i), exten, dpc, i);
+                               if (includecount >= AST_PBX_MAX_STACK) {
+                                       ast_log(LOG_WARNING, "Maximum include depth exceeded!\n");
+                               } else {
+                                       int dupe = 0;
+                                       int x;
+                                       for (x = 0; x < includecount; x++) {
+                                               if (!strcasecmp(includes[x], ast_get_include_name(i))) {
+                                                       dupe++;
+                                                       break;
+                                               }
+                                       }
+                                       if (!dupe) {
+                                               includes[includecount] = ast_get_include_name(i);
+                                               manager_show_dialplan_helper(s, m, actionidtext, ast_get_include_name(i), exten, dpc, i, includecount + 1, includes);
+                                       } else {
+                                               ast_log(LOG_WARNING, "Avoiding circular include of %s within %s\n", ast_get_include_name(i), context);
+                                       }
+                               }
                        } else {
                                if (!dpc->total_items++)
                                        manager_dpsendack(s, m);
@@ -8609,6 +8627,7 @@ static int manager_show_dialplan(struct mansession *s, const struct message *m)
 {
        const char *exten, *context;
        const char *id = astman_get_header(m, "ActionID");
+       const char *incstack[AST_PBX_MAX_STACK];
        char idtext[256];
 
        /* Variables used for different counters */
@@ -8624,7 +8643,7 @@ static int manager_show_dialplan(struct mansession *s, const struct message *m)
        exten = astman_get_header(m, "Extension");
        context = astman_get_header(m, "Context");
 
-       manager_show_dialplan_helper(s, m, idtext, context, exten, &counters, NULL);
+       manager_show_dialplan_helper(s, m, idtext, context, exten, &counters, NULL, 0, incstack);
 
        if (!ast_strlen_zero(context) && !counters.context_existence) {
                char errorbuf[BUFSIZ];