]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
AST-2018-005: Fix tdata leaks when calling pjsip_endpt_send_response(2)
authorGeorge Joseph <gjoseph@digium.com>
Tue, 6 Feb 2018 17:28:49 +0000 (10:28 -0700)
committerGeorge Joseph <gjoseph@digium.com>
Wed, 21 Feb 2018 14:39:38 +0000 (07:39 -0700)
pjsip_distributor:
   authenticate() creates a tdata and uses it to send a challenge or
   failure response.  When pjsip_endpt_send_response2() succeeds, it
   automatically decrements the tdata ref count but when it fails, it
   doesn't.  Since we weren't checking for a return status, we weren't
   decrementing the count ourselves on error and were therefore leaking
   tdatas.

res_pjsip_session:
   session_reinvite_on_rx_request wasn't decrementing the ref count
   if an error happened while sending a 491 response.
   pre_session_setup wasn't decrementing the ref count if
   while sending an error after a pjsip_inv_verify_request failure.

res_pjsip:
   ast_sip_send_response wasn't decrementing the ref count on error.

ASTERISK-27618
Reported By: Sandro Gauci

Change-Id: Iab33a6c7b6fba96148ed465b690ba8534ac961bf

res/res_pjsip.c
res/res_pjsip/pjsip_distributor.c
res/res_pjsip_session.c

index 293665d6683522e18ca7164f3a1f49b73d77ca13..47221f8097fb48ba6be0c796a3793fa496d80955 100644 (file)
@@ -4466,9 +4466,15 @@ static void supplement_outgoing_response(pjsip_tx_data *tdata, struct ast_sip_en
 
 int ast_sip_send_response(pjsip_response_addr *res_addr, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
 {
+       pj_status_t status;
+
        supplement_outgoing_response(tdata, sip_endpoint);
+       status = pjsip_endpt_send_response(ast_sip_get_pjsip_endpoint(), res_addr, tdata, NULL, NULL);
+       if (status != PJ_SUCCESS) {
+               pjsip_tx_data_dec_ref(tdata);
+       }
 
-       return pjsip_endpt_send_response(ast_sip_get_pjsip_endpoint(), res_addr, tdata, NULL, NULL);
+       return status == PJ_SUCCESS ? 0 : -1;
 }
 
 int ast_sip_send_stateful_response(pjsip_rx_data *rdata, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
index 591d7fea761bd06b364eb3f72542599e7a42ac89..e056b608ec5cc893a79df2ef280c87c70100dd08 100644 (file)
@@ -844,7 +844,9 @@ static pj_bool_t authenticate(pjsip_rx_data *rdata)
                case AST_SIP_AUTHENTICATION_CHALLENGE:
                        /* Send the 401 we created for them */
                        ast_sip_report_auth_challenge_sent(endpoint, rdata, tdata);
-                       pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL);
+                       if (pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL) != PJ_SUCCESS) {
+                               pjsip_tx_data_dec_ref(tdata);
+                       }
                        return PJ_TRUE;
                case AST_SIP_AUTHENTICATION_SUCCESS:
                        /* See note in endpoint_lookup about not holding an unnecessary write lock */
@@ -857,7 +859,9 @@ static pj_bool_t authenticate(pjsip_rx_data *rdata)
                case AST_SIP_AUTHENTICATION_FAILED:
                        log_failed_request(rdata, "Failed to authenticate", 0, 0);
                        ast_sip_report_auth_failed_challenge_response(endpoint, rdata);
-                       pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL);
+                       if (pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL) != PJ_SUCCESS) {
+                               pjsip_tx_data_dec_ref(tdata);
+                       }
                        return PJ_TRUE;
                case AST_SIP_AUTHENTICATION_ERROR:
                        log_failed_request(rdata, "Error to authenticate", 0, 0);
index 8939f4345bfa1e358589c5bbe4ffd2f17a5c5ba1..d74796e519d732c4f34777bb83cc36b2090ffde0 100644 (file)
@@ -1083,7 +1083,9 @@ static pj_bool_t session_reinvite_on_rx_request(pjsip_rx_data *rdata)
 
                /* Otherwise this is a new re-invite, so reject it */
                if (pjsip_dlg_create_response(dlg, rdata, 491, NULL, &tdata) == PJ_SUCCESS) {
-                       pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL);
+                       if (pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL) != PJ_SUCCESS) {
+                               pjsip_tx_data_dec_ref(tdata);
+                       }
                }
 
                return PJ_TRUE;
@@ -2051,7 +2053,9 @@ static pjsip_inv_session *pre_session_setup(pjsip_rx_data *rdata, const struct a
 
        if (pjsip_inv_verify_request(rdata, &options, NULL, NULL, ast_sip_get_pjsip_endpoint(), &tdata) != PJ_SUCCESS) {
                if (tdata) {
-                       pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL);
+                       if (pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL) != PJ_SUCCESS) {
+                               pjsip_tx_data_dec_ref(tdata);
+                       }
                } else {
                        pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
                }