[asterisk-dev] [Code Review] Fix memory leak, possible crash in sip show peers

Matt Jordan reviewboard at asterisk.org
Tue Feb 14 16:44:40 CST 2012


-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://reviewboard.asterisk.org/r/1738/
-----------------------------------------------------------

(Updated Feb. 14, 2012, 4:44 p.m.)


Review request for Asterisk Developers, Mark Michelson and rmudgett.


Changes
-------

Addressed mmichelson's comments.

rmudgett also discussed Kevin's approach with me that would be less work in astobj2.  As Kevin pointed out in the initial comment, this same result could be accomplished in chan_sip using a callback function that used the OBJ_MULTIPLE and simply having it select all of the objects in the container.  I thought again about dumping this patch and going with that approach, as it's perfectly valid and would be less work then this patch is.  However, I still like the addition of an iterator that does this itself for two reasons:
1) It keeps all of the logic for creating the iterator and what it iterates over within astobj2
2) It results in having one less function in chan_sip

The callback function approach is certainly more flexible then what this patch adds, but having an iterator that is a snapshot of the current contents of a container is a fairly common need, and this removes having to have callback functions every time we need that.

Unless rmudgett or anyone else is adamantly opposed to having a simpler mechanism to produce what the callback approach gives us, I'll go with this patch.


Summary
-------

The SIP show peers command stores pointers to the current peers in the peers container in a fixed size array.  The size of this array is determined a bit before iterating through the peers container.  The container is not locked during the array initialization, nor while the iterator is initialized.  There are at least two problems with this:
1) The array is allocated at the beginning of the method.  There are a number of exit points from the function that occur before the array is deallocated, resulting in a memory leak.
2) The array size is supposed to be the current number of peers in the container.  However, the peers container is not locked when the size is determined, and the version of the iterator is not set until ao2_iterator_next is called.  Thus, any items added to the peers container prior to the first traversal of the container will be "counted" during the traversal, and the array can be overrun.

This would typically occur if some other thread performed a sip reload at the same time as the sip show peers command, and additional peers were added in between when the array was sized and when the peers were traversed.

This patch takes a bit more of a pessimistic view of the thread-safety involved with showing the peers.  We lock the container during the period that we build the array for sorting and when we initialize the ao2_iterator.  The ao2_iterator initialization has been modified as well to set the version to the container version, as opposed to waiting for the first traversal of the container.  This should be safe:
1) If an item is added to the container prior to/while traversing it, the version number of that item will be greater then the version of iterator, and will be ignored
2) If an item is removed from the container prior to/while traversing it, the number of items added to the array will be less then the array size, which is acceptable

Note that you can still have a situation where a reload occurs during a sip show peers which changes what the command will output while it is building the peer array; however, that's no different then the current behavior.  The only way to prevent that would be to lock the peers container during the entire traversal, which would potentially impact performance on normal SIP operations.


Diffs (updated)
-----

  /branches/1.8/channels/chan_sip.c 355276 
  /branches/1.8/include/asterisk/astobj2.h 355276 
  /branches/1.8/main/astobj2.c 355276 

Diff: https://reviewboard.asterisk.org/r/1738/diff


Testing
-------

Basic testing involving running sip show peers and reloading.  More testing will need to be done by the issue reporter, who was performing "sip reloads" alongside a script that ran "sip show peers" once a second.


Thanks,

Matt

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-dev/attachments/20120214/5eb13d38/attachment.htm>


More information about the asterisk-dev mailing list