summaryrefslogtreecommitdiff
path: root/channels/sig_pri.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2015-05-12 17:34:45 -0500
committerRichard Mudgett <rmudgett@digium.com>2015-05-12 17:43:35 -0500
commit0bb0d4a60352fcf0c73df123e53b76cc733de11a (patch)
tree534491234719e7a5e6d581f426841f0616f80fb4 /channels/sig_pri.c
parent3858e67dd549cf600fe1ed0c814affd9fb64c708 (diff)
chan_dahdi/sig_pri: Fix crash on ISDN call hangup collision.
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
Diffstat (limited to 'channels/sig_pri.c')
-rw-r--r--channels/sig_pri.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/channels/sig_pri.c b/channels/sig_pri.c
index c58a3f358..71e7e23de 100644
--- a/channels/sig_pri.c
+++ b/channels/sig_pri.c
@@ -7090,10 +7090,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);
@@ -7234,10 +7235,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)) {