[asterisk-dev] [asterisk-commits] dvossel: trunk r256319 - /trunk/channels/chan_sip.c
Russell Bryant
russell at digium.com
Sat Apr 10 09:55:51 CDT 2010
I missed the code review on this one, but I do have some comments ...
----- "SVN commits to the Asterisk project" <asterisk-commits at lists.digium.com> wrote:
> Author: dvossel
> Date: Tue Apr 6 09:42:10 2010
> New Revision: 256319
>
> URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=256319
> Log:
> fixes deadlock in chan_sip caused by usage of MASTER_CHANNEL dialplan
> function
>
> (closes issue #16767)
> Reported by: lmsteffan
> Patches:
> deadlock_16767v3.diff uploaded by dvossel (license 671)
>
>
> Modified:
> trunk/channels/chan_sip.c
>
> Modified: trunk/channels/chan_sip.c
> URL:
> http://svnview.digium.com/svn/asterisk/trunk/channels/chan_sip.c?view=diff&rev=256319&r1=256318&r2=256319
> ==============================================================================
> --- trunk/channels/chan_sip.c (original)
> +++ trunk/channels/chan_sip.c Tue Apr 6 09:42:10 2010
> @@ -17495,7 +17495,6 @@
>
> owner = p->owner;
> if (owner) {
> - char causevar[256], causeval[256];
> const char *rp = NULL, *rh = NULL;
>
> owner->hangupcause = 0;
> @@ -17513,10 +17512,6 @@
>
> if (!owner->hangupcause)
> owner->hangupcause = hangup_sip2cause(resp);
> -
> - snprintf(causevar, sizeof(causevar),
> "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name);
> - snprintf(causeval, sizeof(causeval), "SIP %s",
> REQ_OFFSET_TO_STR(req, rlPart2));
> - pbx_builtin_setvar_helper(owner, causevar, causeval);
> }
>
> if (p->socket.type == SIP_TRANSPORT_UDP) {
> @@ -20922,10 +20917,26 @@
> ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting
> %d)\n", seqno, p->ocseq);
> return -1;
> } else {
> + char causevar[256], causeval[256];
> +
> if ((respid == 200) || ((respid >= 300) && (respid <= 399))) {
> extract_uri(p, req);
> }
> +
> handle_response(p, respid, e + len, req, seqno);
> +
> + if (p->owner) {
> + struct ast_channel *owner = p->owner;
> +
> + snprintf(causevar, sizeof(causevar),
> "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name);
> + snprintf(causeval, sizeof(causeval), "SIP %s",
> REQ_OFFSET_TO_STR(req, rlPart2));
> +
> + sip_pvt_unlock(p);
> + ast_channel_unlock(owner);
> + *nounlock = 1;
> + pbx_builtin_setvar_helper(owner, causevar, causeval);
> + sip_pvt_lock(p);
> + }
> }
> return 0;
> }
What guarantees that owner is a valid channel in this code? Based on my reading, there is nothing that guarantees that the channel will not get freed out from under this code. A reference needs to be taken on p->owner before the unlocks to resolve this.
--
Russell Bryant
Digium, Inc. | Engineering Manager, Open Source Software
445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
jabber: rbryant at digium.com -=- skype: russell-bryant
www.digium.com -=- www.asterisk.org -=- blogs.asterisk.org
More information about the asterisk-dev
mailing list