diff options
author | Etienne Lessard <elessard@proformatique.com> | 2016-08-29 08:10:34 -0400 |
---|---|---|
committer | Etienne Lessard <elessard@proformatique.com> | 2016-08-29 08:10:34 -0400 |
commit | 27951792c4c6b410f51dbe55526f3166e6183a85 (patch) | |
tree | b9583bc46d887027f910d124b061986374c50d8f /main/pbx.c | |
parent | 1b91adf7a1c5e9febfbd9704a9ab5c8d153d6797 (diff) |
pbx.c: Prevent infinite recursion in manager_show_dialplan_helper.
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
Diffstat (limited to 'main/pbx.c')
-rw-r--r-- | main/pbx.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/main/pbx.c b/main/pbx.c index 3b9594a19..5002999b4 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -5745,7 +5745,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; @@ -5827,7 +5828,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); @@ -5882,6 +5900,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 */ @@ -5897,7 +5916,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]; |