]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res/res_pjsip: Fix off nominal crash with requests that fail and have a timer 40/1640/1
authorMatt Jordan <mjordan@digium.com>
Mon, 16 Nov 2015 19:56:49 +0000 (13:56 -0600)
committerMatt Jordan <mjordan@digium.com>
Mon, 16 Nov 2015 20:09:55 +0000 (14:09 -0600)
When a request is sent using pjsip_endpt_send_request and fails, a condition
exists where the request wrapper, which is an AO2 object, may be de-ref'd
more times than it should. This occurs when the request's callback is called,
and, in the callback, the timer on the PJSIP heap is cancelled. When that
occurs, the request wrapper's lifetime is decremented. When
pjsip_endpt_send_request fails, we unilaterally decrement the lifetime of
the request wrapper again, even though we've already cancelled the reference
associated with the timer.

This patch checks the return result of pj_timer_heap_cancel_if_active before
removing the reference associated with the timer. We now only decrement it
in this case if a timer is cancelled as a result of the function call.

Change-Id: I21332343a1a019c1117076f9bf2df27be2850102

res/res_pjsip.c

index 9d0540d420b97f1251dc5b5dd60090d265637f76..a4748d20e4f2a3bcfa8f13386f36223e13728bb3 100644 (file)
@@ -3151,9 +3151,11 @@ static pj_status_t endpt_send_request(struct ast_sip_endpoint *endpoint,
                char errmsg[PJ_ERR_MSG_SIZE];
 
                if (timeout > 0) {
-                       pj_timer_heap_cancel_if_active(pjsip_endpt_get_timer_heap(endpt),
+                       int timers_cancelled = pj_timer_heap_cancel_if_active(pjsip_endpt_get_timer_heap(endpt),
                                req_wrapper->timeout_timer, TIMER_INACTIVE);
-                       ao2_ref(req_wrapper, -1);
+                       if (timers_cancelled > 0) {
+                               ao2_ref(req_wrapper, -1);
+                       }
                }
 
                /* Complain of failure to send the request. */