From 4ad78be57ff4008e65134dd676abffd653071fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= Date: Tue, 24 Dec 2019 11:04:38 -0500 Subject: [PATCH] sipcall: avoid use after free on the invite session pjsip uses a counter to delete objects when the ref counter is equals to 0. This means that our unique_ptr on the invite will be invalid if resources are already freed by pjproject. To avoid this, we need to increment and decrement the counter when we respectively create and destroy our unique_ptr on the invite session Change-Id: Ida5c687004b91100f1c10f83e32c1a40264c775c --- src/sip/sipcall.cpp | 3 +++ src/sip/sipvoiplink.cpp | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp index dca849a2f..3a6a7e908 100644 --- a/src/sip/sipcall.cpp +++ b/src/sip/sipcall.cpp @@ -1329,7 +1329,10 @@ SIPCall::InvSessionDeleter::operator ()(pjsip_inv_session* inv) const noexcept { // prevent this from getting accessed in callbacks // JAMI_WARN: this is not thread-safe! + if (!inv) return; inv->mod_data[getSIPVoIPLink()->getModId()] = nullptr; + // NOTE: the counter is incremented by sipvoiplink (transaction_request_cb) + pjsip_inv_dec_ref(inv); } bool diff --git a/src/sip/sipvoiplink.cpp b/src/sip/sipvoiplink.cpp index aa055ba82..8995b100e 100644 --- a/src/sip/sipvoiplink.cpp +++ b/src/sip/sipvoiplink.cpp @@ -385,6 +385,11 @@ transaction_request_cb(pjsip_rx_data *rdata) pjsip_dlg_dec_lock(dialog); inv->mod_data[mod_ua_.id] = call.get(); + // NOTE: The invitation counter is managed by pjsip. If that counter goes down to zero + // the invite will be destroyed, and the unique_ptr will point freed datas. + // To avoid this, we increment the ref counter and let our unique_ptr manage + // when the invite will be freed + pjsip_inv_add_ref(inv); call->inv.reset(inv); // Check whether Replaces header is present in the request and process accordingly.