From 0d487b53b13e9debb51ad8fe84b3767de5d25d75 Mon Sep 17 00:00:00 2001
From: Matt Jordan <mjordan@digium.com>
Date: Fri, 24 Jun 2016 19:55:09 -0500
Subject: [PATCH] res/res_pjsip_session: Check for presence of an active
 negotiator

It is possible in a hypothetical situation for a session refresh to be
invoked on a PJSIP when the negotiatior on the INVITE session has not
yet been established. While this shouldn't occur with existing uses of
ast_sip_session_refresh, the crashes that occur due to improperly
calling PJSIP functions that expect a non-NULL negotiatior are
avoidable. PJSIP will create the negotiator in pjsip_inv_reinvite; this
means that simply checking for the presence of the negotiator before
passing it to other PJSIP functions that use it is allowable. As such,
this patch adds checks for the presence of the negotiator before calling
PJSIP functions that assume it is non-NULL.

Change-Id: I1028323e7e01b0a531865e5412a71b6f6ec4276d
---
 res/res_pjsip_session.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 9f98e34b83..a773c16fc0 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -792,12 +792,14 @@ static int delay_request(struct ast_sip_session *session,
 static pjmedia_sdp_session *generate_session_refresh_sdp(struct ast_sip_session *session)
 {
 	pjsip_inv_session *inv_session = session->inv_session;
-	const pjmedia_sdp_session *previous_sdp;
+	const pjmedia_sdp_session *previous_sdp = NULL;
 
-	if (pjmedia_sdp_neg_was_answer_remote(inv_session->neg)) {
-		pjmedia_sdp_neg_get_active_remote(inv_session->neg, &previous_sdp);
-	} else {
-		pjmedia_sdp_neg_get_active_local(inv_session->neg, &previous_sdp);
+	if (inv_session->neg) {
+		if (pjmedia_sdp_neg_was_answer_remote(inv_session->neg)) {
+			pjmedia_sdp_neg_get_active_remote(inv_session->neg, &previous_sdp);
+		} else {
+			pjmedia_sdp_neg_get_active_local(inv_session->neg, &previous_sdp);
+		}
 	}
 	return create_local_sdp(inv_session, session, previous_sdp);
 }
@@ -917,7 +919,9 @@ int ast_sip_session_refresh(struct ast_sip_session *session,
 
 	if (generate_new_sdp) {
 		/* SDP can only be generated if current negotiation has already completed */
-		if (pjmedia_sdp_neg_get_state(inv_session->neg) != PJMEDIA_SDP_NEG_STATE_DONE) {
+		if (inv_session->neg
+			&& pjmedia_sdp_neg_get_state(inv_session->neg)
+				!= PJMEDIA_SDP_NEG_STATE_DONE) {
 			ast_debug(3, "Delay session refresh with new SDP to %s because SDP negotiation is not yet done...\n",
 				ast_sorcery_object_get_id(session->endpoint));
 			return delay_request(session, on_request_creation, on_sdp_creation,