From a20eff526e22b0236fd1d097b727580a0236e009 Mon Sep 17 00:00:00 2001
From: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
Date: Thu, 23 Feb 2017 14:48:20 -0500
Subject: [PATCH] sipcall: fix nullptr access in remote sdp handling

sipvoiplink code may set remote sdp to nullptr and this case was not
handled correctly later.
This patch fixes that by not using the nullptr to set ICE call transport.
Also moved the code to use the remote sdp, duplicated, into sipcall
for factorization.

Change-Id: I6dcfd3bebed3fd754c91dd7f2cab7ca110d3de09
---
 src/sip/sipcall.cpp     | 25 ++++++++++++++++++-------
 src/sip/sipcall.h       |  6 ++++++
 src/sip/sipvoiplink.cpp | 12 ++----------
 3 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp
index 440d7808ce..14008b5657 100644
--- a/src/sip/sipcall.cpp
+++ b/src/sip/sipcall.cpp
@@ -1000,13 +1000,8 @@ SIPCall::onReceiveOffer(const pjmedia_sdp_session* offer)
         acc.getActiveAccountCodecInfoList(MEDIA_AUDIO),
         acc.getActiveAccountCodecInfoList(acc.isVideoEnabled() ? MEDIA_VIDEO : MEDIA_NONE),
         acc.getSrtpKeyExchange(),
-        getState() == CallState::HOLD
-    );
-    auto ice_attrs = Sdp::getIceAttributes(offer);
-    if (not ice_attrs.ufrag.empty() and not ice_attrs.pwd.empty()) {
-        if (initIceTransport(false))
-            setupLocalSDPFromIce();
-    }
+        getState() == CallState::HOLD);
+    setRemoteSdp(offer);
     sdp_->startNegotiation();
     pjsip_inv_set_sdp_answer(inv.get(), sdp_->getLocalSdpSession());
 }
@@ -1136,4 +1131,20 @@ SIPCall::merge(const std::shared_ptr<SIPCall>& scall)
         waitForIceAndStartMedia();
 }
 
+void
+SIPCall::setRemoteSdp(const pjmedia_sdp_session* sdp)
+{
+    if (!sdp)
+        return;
+
+    auto ice_attrs = Sdp::getIceAttributes(sdp);
+    if (not ice_attrs.ufrag.empty() and not ice_attrs.pwd.empty()) {
+        if (not getIceTransport()) {
+            RING_DBG("Initializing ICE transport");
+            initIceTransport(false);
+        }
+        setupLocalSDPFromIce();
+    }
+}
+
 } // namespace ring
diff --git a/src/sip/sipcall.h b/src/sip/sipcall.h
index c7542f6ffc..d5bc13a97a 100644
--- a/src/sip/sipcall.h
+++ b/src/sip/sipcall.h
@@ -224,6 +224,12 @@ class SIPCall : public Call
             peerRegistredName_ = name;
         }
 
+        /**
+         * Give peer SDP to the call for handling
+         * @param sdp pointer on PJSIP sdp structure, could be nullptr (acts as no-op in such case)
+         */
+        void setRemoteSdp(const pjmedia_sdp_session* sdp);
+
     private:
         NON_COPYABLE(SIPCall);
 
diff --git a/src/sip/sipvoiplink.cpp b/src/sip/sipvoiplink.cpp
index 548b91ba2d..413ab8682e 100644
--- a/src/sip/sipvoiplink.cpp
+++ b/src/sip/sipvoiplink.cpp
@@ -335,16 +335,8 @@ transaction_request_cb(pjsip_rx_data *rdata)
     call->getSDP().receiveOffer(r_sdp,
         account->getActiveAccountCodecInfoList(MEDIA_AUDIO),
         account->getActiveAccountCodecInfoList(account->isVideoEnabled() ? MEDIA_VIDEO : MEDIA_NONE),
-        account->getSrtpKeyExchange()
-    );
-    auto ice_attrs = Sdp::getIceAttributes(r_sdp);
-    if (not ice_attrs.ufrag.empty() and not ice_attrs.pwd.empty()) {
-        if (not call->getIceTransport()) {
-            RING_DBG("Initializing ICE transport");
-            call->initIceTransport(false);
-        }
-        call->setupLocalSDPFromIce();
-    }
+        account->getSrtpKeyExchange());
+    call->setRemoteSdp(r_sdp);
 
     pjsip_dialog *dialog = nullptr;
     if (pjsip_dlg_create_uas_and_inc_lock(pjsip_ua_instance(), rdata, nullptr, &dialog) != PJ_SUCCESS) {
-- 
GitLab