[Asterisk-Dev] [PATCH] Fix crash on PRI channel hangup

Simon Kirby sim at netnation.com
Wed Mar 3 23:44:11 MST 2004


'lo,

Just subscribed to the list (and development in general).  We've been
testing Asterisk by running a TE410P crossed-over to a PRI card in our
existing PBX, and we've run in to a problem (in Debian 0.7.2-4 and the
stable branch from today) where hanging up a call forwarded through
Asterisk (one PRI channel in, one PRI out) causes a NULL pointer
deference.

The log at the time of crash looks like this:

    -- Channel 1, span 1 got hangup
    -- Hungup 'Zap/2-1'
  == Spawn extension (default, 1002, 1) exited non-zero on 'Zap/1-1'
    -- Hungup 'Zap/1-1'

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 196621 (LWP 1743)]
0x4065afee in pri_dchannel (vpri=0x40668040) at chan_zap.c:6500
6500	pri->pvt[chan]->owner->hangupcause = hangup_pri2cause(e->hangup.cause);

The code in question looks like this:

	if (!pri->pvt[chan]->alreadyhungup) {
		/* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
		pri->pvt[chan]->alreadyhungup = 1;
		pri->pvt[chan]->owner->hangupcause = hangup_pri2cause(e->hangup.cause);
		/* Queue a BUSY instead of a hangup if our cause is appropriate */
		if (pri->pvt[chan]->owner) {
			switch(e->hangup.cause) {
			case PRI_CAUSE_USER_BUSY:
				pri->pvt[chan]->subs[SUB_REAL].needbusy =1;

Note the check for "pri->pvt[chan]->owner" after deferencing it on the
line before.  My guess is that we are hitting this bug because of the
possibly-rare case of forwarding in and out the same PRI line for the
same call.  Mostly-obvious patch as follows:

--- channels/chan_zap.c.orig	2004-03-03 17:42:33.000000000 -0800
+++ channels/chan_zap.c	2004-03-03 18:19:15.000000000 -0800
@@ -6497,9 +6497,9 @@
 						if (!pri->pvt[chan]->alreadyhungup) {
 							/* we're calling here zt_hangup so once we get there we need to clear p->call after calling pri_hangup */
 							pri->pvt[chan]->alreadyhungup = 1;
-							pri->pvt[chan]->owner->hangupcause = hangup_pri2cause(e->hangup.cause);
 							/* Queue a BUSY instead of a hangup if our cause is appropriate */
 							if (pri->pvt[chan]->owner) {
+								pri->pvt[chan]->owner->hangupcause = hangup_pri2cause(e->hangup.cause);
 								switch(e->hangup.cause) {
 								case PRI_CAUSE_USER_BUSY:
 									pri->pvt[chan]->subs[SUB_REAL].needbusy =1;


Simon-



More information about the asterisk-dev mailing list