]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
cdr.c: Fix runtime leak of CDR records.
authorRichard Mudgett <rmudgett@digium.com>
Fri, 9 Feb 2018 18:06:08 +0000 (12:06 -0600)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 9 Feb 2018 20:25:25 +0000 (14:25 -0600)
Need to remove all CDR's listed by a CDR object from the active_cdrs_all
container including the root/master record.

ASTERISK-27656

Change-Id: I48b4970663fea98baa262593d2204ef304aaf80e

main/cdr.c

index 90371a46a53218716730dd770d25115803ab52e3..3e02c3e3e894ca2f04be68333a6a0bcbf416f37f 100644 (file)
@@ -371,7 +371,7 @@ static ast_cond_t cdr_pending_cond;
 /*! \brief A container of the active master CDRs indexed by Party A channel uniqueid */
 static struct ao2_container *active_cdrs_master;
 
-/*! \brief A container of all active CDRs indexed by Party B channel name */
+/*! \brief A container of all active CDRs with a Party B indexed by Party B channel name */
 static struct ao2_container *active_cdrs_all;
 
 /*! \brief Message router for stasis messages regarding channel state */
@@ -971,13 +971,21 @@ static void cdr_all_unlink(struct cdr_object *cdr)
 
        ast_assert(cdr->is_root);
 
+       /* Hold a ref to the root CDR to ensure the list members don't go away on us. */
+       ao2_ref(cdr, +1);
        ao2_lock(active_cdrs_all);
-       for (cur = cdr->next; cur; cur = next) {
+       for (cur = cdr; cur; cur = next) {
                next = cur->next;
                ao2_unlink_flags(active_cdrs_all, cur, OBJ_NOLOCK);
+               /*
+                * It is safe to still use cur after unlinking because the
+                * root CDR holds a ref to all the CDRs in the list and we
+                * have a ref to the root CDR.
+                */
                ast_string_field_set(cur, party_b_name, "");
        }
        ao2_unlock(active_cdrs_all);
+       ao2_ref(cdr, -1);
 }
 
 /*!