[asterisk-dev] race condition on bridge/masquerading?

Guillermo Winkler gwinkler at inconcertcc.com
Sat Mar 7 18:11:43 CST 2009


Hi, I'm having some crashes on local channel hangup always related to the
BRIDGEPEER channel variable.

 

I think there's a problem in ast_channel_bridge, when the calls get checked
for zombieness 

 

                

                               /* Stop if we're a zombie or need a soft
hangup */

                               if (ast_test_flag(c0, AST_FLAG_ZOMBIE) ||
ast_check_hangup_locked(c0) ||

                                   ast_test_flag(c1, AST_FLAG_ZOMBIE) ||
ast_check_hangup_locked(c1)) {

                                               *fo = NULL;

                                               if (who)

                                                               *rc = who;

                                               res = 0;

                                               ast_log(LOG_DEBUG, "Bridge
stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags:
%s,%s,%s,%s\n",

                                                               c0->name,
c1->name,

 
ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",

 
ast_check_hangup(c0) ? "Yes" : "No",

 
ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",

 
ast_check_hangup(c1) ? "Yes" : "No");

                                               break;

                               }

 

                               /* See if the BRIDGEPEER variable needs to be
updated */

                               if
(!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))

                                               pbx_builtin_setvar_helper(c0,
"BRIDGEPEER", c1->name);

                               if
(!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))

                                               pbx_builtin_setvar_helper(c1,
"BRIDGEPEER", c0->name);

 

It's not done inside a lock, as it's done inside ast_do_masquerade(struct
ast_channel *original) when the clone masquerading member gets destroyed.

 

In all the crashes I've seen with gdb it's always freeing the BRIDGEPEER
variable with a value of local,1 <zombie>, so it was caught in the middle of
the masquerading process.

 

I think access to channel->name should be done inside a lock that also
checks for zombieness to be sure we're always touching valid memory.(or
better yet, to check the bridge is going through  masquerading and stop
touching channel members completely)

 

Thoughts?

 

Thanks,

Guille



-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.digium.com/pipermail/asterisk-dev/attachments/20090307/8d90ffe2/attachment.htm 


More information about the asterisk-dev mailing list