]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fixed invalid memory access when adding extension to pattern match tree
authorMatthew Jordan <mjordan@digium.com>
Mon, 31 Oct 2011 15:58:06 +0000 (15:58 +0000)
committerMatthew Jordan <mjordan@digium.com>
Mon, 31 Oct 2011 15:58:06 +0000 (15:58 +0000)
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
main/pbx.c

index 37193309c661c6f32f906508f6d3a1c15a33758d..8221dc8361b6d22deacbf5af1a559ea3d475fcfe 100644 (file)
@@ -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;
 
index 258ef14166d45c46a69cd3f650cd7660a0ae46d4..bd3e7a999e60b73e893304c212d450b981563ee7 100644 (file)
@@ -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;