Language: C
Label: safe
CWE: CWE-416 \u2014 Use After Free
Referencing memory after it has been freed can cause a program to crash, use unexpected values, or execute code.

Code:
static pj_status_t transport_destroy  (pjmedia_transport *tp)
{
    transport_srtp *srtp = (transport_srtp *) tp;
    pj_status_t status;
    unsigned i;

    PJ_ASSERT_RETURN(tp, PJ_EINVAL);

    PJ_LOG(4, (srtp->pool->obj_name, "Destroying SRTP transport"));

    /* Close all keying. Note that any keying should not be destroyed before
     * SRTP transport is destroyed as re-INVITE may initiate new keying method
     * without destroying SRTP transport.
     */
    for (i=0; i < srtp->all_keying_cnt; i++)
        pjmedia_transport_close(srtp->all_keying[i]);

    /* Close member if configured */
    if (srtp->setting.close_member_tp && srtp->member_tp) {
        pjmedia_transport_close(srtp->member_tp);
    }

    status = pjmedia_transport_srtp_stop(tp);

    if (srtp->base.grp_lock) {
        pj_grp_lock_dec_ref(srtp->base.grp_lock);
    } else {
        /* Only get here when the underlying transport does not have
         * a group lock, race condition with callbacks may occur.
         * Currently UDP, ICE, and loop have a group lock already.
         */
        PJ_LOG(4,(srtp->pool->obj_name,
                  "Warning: underlying transport does not have group lock"));

        /* In case mutex is being acquired by other thread.
         * An effort to synchronize destroy() & callbacks when the underlying
         * transport does not provide a group lock.
         */
        pj_lock_acquire(srtp->mutex);
        pj_lock_release(srtp->mutex);

        srtp_on_destroy(srtp);
    }

    return status;
}