From 8765a8035599f1996a41c2ecf73b01ce6ffad998 Mon Sep 17 00:00:00 2001 From: Matthew Jordan Date: Mon, 31 Oct 2011 15:58:06 +0000 Subject: [PATCH] Fixed invalid memory access when adding extension to pattern match tree When an extension is removed from a context, its entry in the pattern match tree is not deleted. Instead, the extension is marked as deleted. When an extension is removed and re-added, if that extension is also a prefix of another extension, several log messages would report an error and did not check whether or not the extension was deleted before accessing the memory. Additionally, if the extension was already in the tree but previously deleted, and the pattern was at the end of a match, the findonly flag was not honored and the extension would be erroneously undeleted. Additionaly, it was discovered that an IAX2 peer could be unregistered via the CLI, while at the same time it could be scheduled for unregistration by Asterisk. The unregistration method now checks to see if the peer was already unregistered before continuing with an unregistration. (closes issue ASTERISK-18135) Reported by: Jaco Kroon, Henry Fernandes, Kristijan Vrban Tested by: Matt Jordan Review: https://reviewboard.asterisk.org/r/1526 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@342769 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_iax2.c | 4 ++++ main/pbx.c | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 37193309c6..8221dc8361 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -8582,6 +8582,10 @@ static void __expire_registry(const void *data) if (!peer) return; + if (peer->expire == -1) { + /* Removed already (possibly through CLI), ignore */ + return; + } peer->expire = -1; diff --git a/main/pbx.c b/main/pbx.c index 258ef14166..bd3e7a999e 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -2055,8 +2055,11 @@ static struct match_char *add_exten_to_pattern_tree(struct ast_context *con, str if (already && (m2 = already_in_tree(m1, buf, pattern)) && m2->next_char) { if (!(*(s1 + 1))) { /* if this is the end of the pattern, but not the end of the tree, then mark this node with the exten... a shorter pattern might win if the longer one doesn't match */ + if (findonly) { + return m2; + } if (m2->exten) { - ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n", m2->exten->exten, e1->exten); + ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n", m2->deleted ? "(deleted/invalid)" : m2->exten->exten, e1->exten); } m2->exten = e1; m2->deleted = 0; @@ -2080,7 +2083,7 @@ static struct match_char *add_exten_to_pattern_tree(struct ast_context *con, str } if (!(*(s1 + 1))) { if (m2 && m2->exten) { - ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n", m2->exten->exten, e1->exten); + ast_log(LOG_WARNING, "Found duplicate exten. Had %s found %s\n", m2->deleted ? "(deleted/invalid)" : m2->exten->exten, e1->exten); } m1->deleted = 0; m1->exten = e1; -- 2.47.2