]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_dahdi/sig_pri: Fix crash on ISDN call hangup collision. 57/457/1
authorRichard Mudgett <rmudgett@digium.com>
Tue, 12 May 2015 22:34:45 +0000 (17:34 -0500)
committerJoshua Colp <jcolp@digium.com>
Wed, 13 May 2015 13:49:09 +0000 (08:49 -0500)
If an ISDN call is hungup by both sides at the same time a crash could
happen.

* Added missing NULL checks for the owner channel after calling
pri_queue_pvt_cause_data() in two places.  Code after those calls need to
check the owner channel pointer for NULL before use because
pri_queue_pvt_cause_data() needs to do deadlock avoidance to lock the
owner and the owner may get hung up.

ASTERISK-21893 #close
Reported by:  Alexandr Gordeev

Change-Id: Ica3e266ebc7a894b41d762326f08653e1904bb9a

channels/sig_pri.c

index 6f17330ec081a8b9c08727762d0c76ac994d9b2b..9a0f5b955e57a8c5c03f631f4de370ab679967f2 100644 (file)
@@ -7116,10 +7116,11 @@ static void *pri_dchannel(void *vpri)
                                                break;
                                        }
                                        if (pri->pvts[chanpos]->owner) {
-                                               int do_hangup = 0;
-
                                                snprintf(cause_str, sizeof(cause_str), "PRI PRI_EVENT_HANGUP (%d)", e->hangup.cause);
                                                pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->hangup.cause);
+                                       }
+                                       if (pri->pvts[chanpos]->owner) {
+                                               int do_hangup = 0;
 
                                                /* Queue a BUSY instead of a hangup if our cause is appropriate */
                                                ast_channel_hangupcause_set(pri->pvts[chanpos]->owner, e->hangup.cause);
@@ -7270,10 +7271,11 @@ static void *pri_dchannel(void *vpri)
                                        break;
                                }
                                if (pri->pvts[chanpos]->owner) {
-                                       int do_hangup = 0;
-
                                        snprintf(cause_str, sizeof(cause_str), "PRI PRI_EVENT_HANGUP_REQ (%d)", e->hangup.cause);
                                        pri_queue_pvt_cause_data(pri, chanpos, cause_str, e->hangup.cause);
+                               }
+                               if (pri->pvts[chanpos]->owner) {
+                                       int do_hangup = 0;
 
                                        ast_channel_hangupcause_set(pri->pvts[chanpos]->owner, e->hangup.cause);
                                        switch (ast_channel_state(pri->pvts[chanpos]->owner)) {