Closed tommybrecher closed 5 years ago
Thank you very much for the detailed troubleshoot! Thanks to the information provided, I managed to easily replicate this and fix it. Note that I've pushed fixes from master down to version 2.4, since that's the last supported version. However, if you are using 2.3, you should be easily cherry-pick the commit in your source tree.
OpenSIPS version you are running
Describe the bug
- During a call setup, a callee sends a 180 ringing simultaneously to the caller sending a CANCEL. - There's a race condition of multiple processes attempting to write the cancel buffer. `t->uac[branch].local_cancel.buffer` - While the process handling the callee's 180 proceeds to cancel_branch() to generate a local cancel, the process handling the callers CANCEL is at should_cancel_branch(). - In some cases `t->uac[b].local_cancel.buffer.s==NULL @t_cancel.h:63` evaluates True but it's not when hitting: `t->uac[b].local_cancel.buffer.s=BUSY_BUFFER` - In most cases this would only cause a memory leak, under some circumstances, when the timing is right if the process handling the calleer's side haven't written into the buffer yet after setting it to BUSY_BUFFER and the process handling the callees side's buffer was overwritten a SEGFAULT occurs. Please see gdb output below while I was reproducing this: ``` sensitive information replaced from the logs breakpoint: break t_cancel.h:67 if t->uac[b].local_cancel.buffer.s != NULL +--t_cancel.h-------------------------------------------------------------------------- |63 if ( t->uac[b].local_cancel.buffer.s==NULL ) { |64 if ( last_received>=100 && last_received<200 ) { |65 /* we'll cancel -- label it so that no one else |66 (e.g. another 200 branch) will try to do the same */ B+>|67 t->uac[b].local_cancel.buffer.s=BUSY_BUFFER; |68 return 1; |69 } else if (last_received==0) { |70 /* set flag to catch the delaied replies */ |71 t->uac[b].flags |= T_UAC_TO_CANCEL_FLAG; |72 } +-------------------------------------------------------------------------------------- (gdb) p t->uac[b].local_cancel.buffer.s $2693 = 0x7fff6a0099c0 "CANCEL sip:402@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.com:5060;transport=UDP SIP/2.0\r\nVia: SIP/2.0/UDP 34.224.106.98:5060;branch=z9hG4bK41e1.cc7c9522.0\r\nFrom: