mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 12:16:00 +00:00
AST-2018-005: Fix tdata leaks when calling pjsip_endpt_send_response(2)
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
This commit is contained in:
@@ -4722,9 +4722,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)
|
int ast_sip_send_response(pjsip_response_addr *res_addr, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
|
||||||
{
|
{
|
||||||
supplement_outgoing_response(tdata, sip_endpoint);
|
pj_status_t status;
|
||||||
|
|
||||||
return pjsip_endpt_send_response(ast_sip_get_pjsip_endpoint(), res_addr, tdata, NULL, NULL);
|
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 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)
|
int ast_sip_send_stateful_response(pjsip_rx_data *rdata, pjsip_tx_data *tdata, struct ast_sip_endpoint *sip_endpoint)
|
||||||
|
@@ -854,7 +854,9 @@ static pj_bool_t authenticate(pjsip_rx_data *rdata)
|
|||||||
case AST_SIP_AUTHENTICATION_CHALLENGE:
|
case AST_SIP_AUTHENTICATION_CHALLENGE:
|
||||||
/* Send the 401 we created for them */
|
/* Send the 401 we created for them */
|
||||||
ast_sip_report_auth_challenge_sent(endpoint, rdata, tdata);
|
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;
|
return PJ_TRUE;
|
||||||
case AST_SIP_AUTHENTICATION_SUCCESS:
|
case AST_SIP_AUTHENTICATION_SUCCESS:
|
||||||
/* See note in endpoint_lookup about not holding an unnecessary write lock */
|
/* See note in endpoint_lookup about not holding an unnecessary write lock */
|
||||||
@@ -867,7 +869,9 @@ static pj_bool_t authenticate(pjsip_rx_data *rdata)
|
|||||||
case AST_SIP_AUTHENTICATION_FAILED:
|
case AST_SIP_AUTHENTICATION_FAILED:
|
||||||
log_failed_request(rdata, "Failed to authenticate", 0, 0);
|
log_failed_request(rdata, "Failed to authenticate", 0, 0);
|
||||||
ast_sip_report_auth_failed_challenge_response(endpoint, rdata);
|
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;
|
return PJ_TRUE;
|
||||||
case AST_SIP_AUTHENTICATION_ERROR:
|
case AST_SIP_AUTHENTICATION_ERROR:
|
||||||
log_failed_request(rdata, "Error to authenticate", 0, 0);
|
log_failed_request(rdata, "Error to authenticate", 0, 0);
|
||||||
|
@@ -1865,7 +1865,9 @@ static pj_bool_t session_reinvite_on_rx_request(pjsip_rx_data *rdata)
|
|||||||
|
|
||||||
/* Otherwise this is a new re-invite, so reject it */
|
/* Otherwise this is a new re-invite, so reject it */
|
||||||
if (pjsip_dlg_create_response(dlg, rdata, 491, NULL, &tdata) == PJ_SUCCESS) {
|
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;
|
return PJ_TRUE;
|
||||||
@@ -2855,7 +2857,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 (pjsip_inv_verify_request(rdata, &options, NULL, NULL, ast_sip_get_pjsip_endpoint(), &tdata) != PJ_SUCCESS) {
|
||||||
if (tdata) {
|
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 {
|
} else {
|
||||||
pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
|
pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user