[asterisk-dev] [Code Review] Fix memory leak, possible crash in sip show peers
Matt Jordan
reviewboard at asterisk.org
Thu Feb 16 13:51:51 CST 2012
-----------------------------------------------------------
This is an automatically generated e-mail. To reply, visit:
https://reviewboard.asterisk.org/r/1738/
-----------------------------------------------------------
(Updated Feb. 16, 2012, 1:51 p.m.)
Review request for Asterisk Developers, Mark Michelson and rmudgett.
Changes
-------
After discussing with Richard, the fact that the only way to know if the allocation for an iterator with the SNAPSHOT flag succeeded would be to 'break' the opacity of the iterator did, indeed, feel a bit to hackish. As such, I went with his suggestion to use the callback with the OBJ_MULTIPLE flag. He posted a patch to create a public container clone method that will go into trunk, which accomplishes some of the intuitiveness that the SNAPSHOT flag was attempting to provide.
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.
This addresses bugs ASTERISK-19231 and ASTERISK-19361.
https://issues.asterisk.org/jira/browse/ASTERISK-19231
https://issues.asterisk.org/jira/browse/ASTERISK-19361
Diffs (updated)
-----
/branches/1.8/channels/chan_sip.c 355620
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/20120216/6e835c1a/attachment-0001.htm>
More information about the asterisk-dev
mailing list