From: Richard Mudgett Date: Tue, 1 May 2012 22:00:11 +0000 (+0000) Subject: * Fix error path resouce leak in local_request(). X-Git-Tag: 11.0.0-beta1~365 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2b7e1affacbfc6cc981e3a5257e9c0c32548f971;p=thirdparty%2Fasterisk.git * Fix error path resouce leak in local_request(). * Restructure local_request() to reduce indentation. ........ Merged revisions 364840 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 364845 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@364846 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_local.c b/channels/chan_local.c index 069f44a2e9..1a8ea17ecd 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -1176,20 +1176,26 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char /*! \brief Part of PBX interface */ static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause) { - struct local_pvt *p = NULL; - struct ast_channel *chan = NULL; + struct local_pvt *p; + struct ast_channel *chan; /* Allocate a new private structure and then Asterisk channel */ - if ((p = local_alloc(data, cap))) { - if (!(chan = local_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL))) { - ao2_unlink(locals, p); - } - if (chan && ast_channel_cc_params_init(chan, requestor ? ast_channel_get_cc_config_params((struct ast_channel *)requestor) : NULL)) { - chan = ast_channel_release(chan); - ao2_unlink(locals, p); - } - ao2_ref(p, -1); /* kill the ref from the alloc */ + p = local_alloc(data, cap); + if (!p) { + return NULL; + } + chan = local_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL); + if (!chan) { + ao2_unlink(locals, p); + } else if (ast_channel_cc_params_init(chan, requestor ? ast_channel_get_cc_config_params((struct ast_channel *)requestor) : NULL)) { + ao2_unlink(locals, p); + p->owner = ast_channel_release(p->owner); + ast_module_user_remove(p->u_owner); + p->chan = ast_channel_release(p->chan); + ast_module_user_remove(p->u_chan); + chan = NULL; } + ao2_ref(p, -1); /* kill the ref from the alloc */ return chan; }