From ba05f4fbdf7162a2406c6a24cac472c64661121f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Fri, 12 Mar 2021 11:09:14 -0500
Subject: [PATCH] pjproject: follow security advisories

Apply patches for CVE-2021-21375 and CVE-2020-15260 affecting
prproject. After a quick look I don't think those issues apply to
us, as GnuTLS manages the TLS part and we do resolution outside
pjsip (the daemon passes ips), but at least our pjproject will
not be affected.

Note, these patches will be removed when we bump pjproject to 2.11.

Change-Id: Ie9029f5501096c7148416cbb803a40f1c053a3d0
---
 .../src/pjproject/0017-CVE-2020-15260.patch   | 129 ++++++++++++++++++
 .../src/pjproject/0018-CVE-2021-21375.patch   |  42 ++++++
 contrib/src/pjproject/package.json            |   4 +-
 contrib/src/pjproject/rules.mak               |   2 +
 4 files changed, 176 insertions(+), 1 deletion(-)
 create mode 100644 contrib/src/pjproject/0017-CVE-2020-15260.patch
 create mode 100644 contrib/src/pjproject/0018-CVE-2021-21375.patch

diff --git a/contrib/src/pjproject/0017-CVE-2020-15260.patch b/contrib/src/pjproject/0017-CVE-2020-15260.patch
new file mode 100644
index 0000000000..350bb402a4
--- /dev/null
+++ b/contrib/src/pjproject/0017-CVE-2020-15260.patch
@@ -0,0 +1,129 @@
+ pjsip/include/pjsip/sip_dialog.h |  1 +
+ pjsip/src/pjsip/sip_dialog.c     | 15 +++++++++++++++
+ pjsip/src/pjsip/sip_transport.c  | 17 +++++++++++++++--
+ pjsip/src/pjsip/sip_util.c       | 11 ++++++++---
+ 4 files changed, 39 insertions(+), 5 deletions(-)
+
+diff --git a/pjsip/include/pjsip/sip_dialog.h b/pjsip/include/pjsip/sip_dialog.h
+index a0214d28c..e314c2ece 100644
+--- a/pjsip/include/pjsip/sip_dialog.h
++++ b/pjsip/include/pjsip/sip_dialog.h
+@@ -165,6 +165,7 @@ struct pjsip_dialog
+     pjsip_route_hdr	route_set;  /**< Route set.			    */
+     pj_bool_t		route_set_frozen; /**< Route set has been set.	    */
+     pjsip_auth_clt_sess	auth_sess;  /**< Client authentication session.	    */
++    pj_str_t		initial_dest;/**< Initial destination host.  	    */
+ 
+     /** Session counter. */
+     int			sess_count; /**< Number of sessions.		    */
+diff --git a/pjsip/src/pjsip/sip_dialog.c b/pjsip/src/pjsip/sip_dialog.c
+index 27530e4f2..9571b5a35 100644
+--- a/pjsip/src/pjsip/sip_dialog.c
++++ b/pjsip/src/pjsip/sip_dialog.c
+@@ -467,6 +467,10 @@ pj_status_t create_uas_dialog( pjsip_user_agent *ua,
+ 
+     /* Save the remote info. */
+     pj_strdup(dlg->pool, &dlg->remote.info_str, &tmp);
++    
++    /* Save initial destination host from transport's info */
++    pj_strdup(dlg->pool, &dlg->initial_dest,
++    	      &rdata->tp_info.transport->remote_name.host);
+ 
+ 
+     /* Init remote's contact from Contact header.
+@@ -1192,6 +1196,12 @@ static pj_status_t dlg_create_request_throw( pjsip_dialog *dlg,
+ 	    return status;
+     }
+ 
++    /* Copy the initial destination host to tdata. This information can be
++     * used later by transport for transport selection.
++     */
++    if (dlg->initial_dest.slen)
++    	pj_strdup(tdata->pool, &tdata->dest_info.name, &dlg->initial_dest);
++
+     /* Done. */
+     *p_tdata = tdata;
+ 
+@@ -1822,6 +1832,11 @@ static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_rx_data *rdata)
+      * transaction as the initial transaction that establishes dialog.
+      */
+     if (dlg->role == PJSIP_ROLE_UAC) {
++    	/* Save initial destination host from transport's info. */
++    	if (!dlg->initial_dest.slen) {
++    	    pj_strdup(dlg->pool, &dlg->initial_dest,
++    	      	      &rdata->tp_info.transport->remote_name.host);
++    	}
+ 
+ 	/* Ignore subsequent request from remote */
+ 	if (msg->type != PJSIP_RESPONSE_MSG)
+diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
+index 784bd069f..2780bd822 100644
+--- a/pjsip/src/pjsip/sip_transport.c
++++ b/pjsip/src/pjsip/sip_transport.c
+@@ -2289,6 +2289,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+ 	int key_len;
+ 	pjsip_transport *tp_ref = NULL;
+ 	transport *tp_entry = NULL;
++	unsigned flag = pjsip_transport_get_flag_from_type(type);
+ 
+ 
+ 	/* If listener is specified, verify that the listener type matches
+@@ -2317,7 +2318,20 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+ 		transport *tp_iter = tp_entry;
+ 		do {
+ 		    /* Don't use transport being shutdown */
+-		    if (!tp_iter->tp->is_shutdown) {
++		    if (!tp_iter->tp->is_shutdown &&
++			!tp_iter->tp->is_destroying) {
++			if ((flag & PJSIP_TRANSPORT_SECURE) && tdata) {
++			    /* For secure transport, make sure tdata's
++			     * destination host matches the transport's
++			     * remote host.
++			     */
++			    if (pj_stricmp(&tdata->dest_info.name,
++				  	   &tp_iter->tp->remote_name.host))
++			    {
++			    	tp_iter = tp_iter->next;
++			    	continue;
++			    }
++			}
+ 			if (sel && sel->type == PJSIP_TPSELECTOR_LISTENER &&
+ 			    sel->u.listener)
+ 			{
+@@ -2336,7 +2350,6 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport2(pjsip_tpmgr *mgr,
+ 	    }
+ 	}
+ 
+-        unsigned flag = pjsip_transport_get_flag_from_type(type);
+ 	if (tp_ref == NULL &&
+ 	    (!sel || sel->disable_connection_reuse == PJ_FALSE))
+ 	{
+diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c
+index d10a6fa30..b235b0ea0 100644
+--- a/pjsip/src/pjsip/sip_util.c
++++ b/pjsip/src/pjsip/sip_util.c
+@@ -1417,7 +1417,10 @@ PJ_DEF(pj_status_t) pjsip_endpt_send_request_stateless(pjsip_endpoint *endpt,
+      */
+     if (tdata->dest_info.addr.count == 0) {
+ 	/* Copy the destination host name to TX data */
+-	pj_strdup(tdata->pool, &tdata->dest_info.name, &dest_info.addr.host);
++	if (!tdata->dest_info.name.slen) {
++	    pj_strdup(tdata->pool, &tdata->dest_info.name,
++	    	      &dest_info.addr.host);
++	}
+ 
+ 	pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, stateless_data,
+ 			     &stateless_send_resolver_callback);
+@@ -1810,8 +1813,10 @@ PJ_DEF(pj_status_t) pjsip_endpt_send_response( pjsip_endpoint *endpt,
+ 	}
+     } else {
+ 	/* Copy the destination host name to TX data */
+-	pj_strdup(tdata->pool, &tdata->dest_info.name, 
+-		  &res_addr->dst_host.addr.host);
++	if (!tdata->dest_info.name.slen) {
++	    pj_strdup(tdata->pool, &tdata->dest_info.name, 
++		      &res_addr->dst_host.addr.host);
++	}
+ 
+ 	pjsip_endpt_resolve(endpt, tdata->pool, &res_addr->dst_host, 
+ 			    send_state, &send_response_resolver_cb);
diff --git a/contrib/src/pjproject/0018-CVE-2021-21375.patch b/contrib/src/pjproject/0018-CVE-2021-21375.patch
new file mode 100644
index 0000000000..b9283f126b
--- /dev/null
+++ b/contrib/src/pjproject/0018-CVE-2021-21375.patch
@@ -0,0 +1,42 @@
+From 97b3d7addbaa720b7ddb0af9bf6f3e443e664365 Mon Sep 17 00:00:00 2001
+From: Nanang Izzuddin <nanang@teluu.com>
+Date: Mon, 8 Mar 2021 16:09:34 +0700
+Subject: [PATCH] Merge pull request from GHSA-hvq6-f89p-frvp
+
+---
+ pjmedia/src/pjmedia/sdp_neg.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/pjmedia/src/pjmedia/sdp_neg.c b/pjmedia/src/pjmedia/sdp_neg.c
+index f4838f75d..9f76b5200 100644
+--- a/pjmedia/src/pjmedia/sdp_neg.c
++++ b/pjmedia/src/pjmedia/sdp_neg.c
+@@ -304,7 +304,6 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(
+ {
+     pjmedia_sdp_session *new_offer;
+     pjmedia_sdp_session *old_offer;
+-    char media_used[PJMEDIA_MAX_SDP_MEDIA];
+     unsigned oi; /* old offer media index */
+     pj_status_t status;
+ 
+@@ -323,8 +322,19 @@ PJ_DEF(pj_status_t) pjmedia_sdp_neg_modify_local_offer2(
+     /* Change state to STATE_LOCAL_OFFER */
+     neg->state = PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER;
+ 
++    /* When there is no active local SDP in state PJMEDIA_SDP_NEG_STATE_DONE,
++     * it means that the previous initial SDP nego must have been failed,
++     * so we'll just set the local SDP offer here.
++     */
++    if (!neg->active_local_sdp) {
++	neg->initial_sdp_tmp = NULL;
++	neg->initial_sdp = pjmedia_sdp_session_clone(pool, local);
++	neg->neg_local_sdp = pjmedia_sdp_session_clone(pool, local);
++
++	return PJ_SUCCESS;
++    }
++
+     /* Init vars */
+-    pj_bzero(media_used, sizeof(media_used));
+     old_offer = neg->active_local_sdp;
+     new_offer = pjmedia_sdp_session_clone(pool, local);
+ 
diff --git a/contrib/src/pjproject/package.json b/contrib/src/pjproject/package.json
index ab5b30fd09..fe6585f405 100644
--- a/contrib/src/pjproject/package.json
+++ b/contrib/src/pjproject/package.json
@@ -19,10 +19,12 @@
         "0014-Add-new-compile-time-setting-PJ_ICE_ST_USE_TURN_PERM.patch",
         "0015-update-local-preference-for-peer-reflexive-candidate.patch",
         "0016-use-addrinfo-instead-CFHOST.patch",
+        "0017-CVE-2020-15260.patch",
+        "0018-CVE-2021-21375.patch",
         "0001-win-config.patch",
         "0002-win-vs-gnutls.patch",
         "0003-win-vs2017-props.patch"
-],
+    ],
     "project_paths": [
         "pjlib-util/build/pjlib_util.vcxproj",
         "pjmedia/build/pjmedia.vcxproj",
diff --git a/contrib/src/pjproject/rules.mak b/contrib/src/pjproject/rules.mak
index 7b7544aee0..330f9c410e 100644
--- a/contrib/src/pjproject/rules.mak
+++ b/contrib/src/pjproject/rules.mak
@@ -61,6 +61,8 @@ pjproject: pjproject-$(PJPROJECT_VERSION).tar.gz .sum-pjproject
 	$(APPLY) $(SRC)/pjproject/0014-Add-new-compile-time-setting-PJ_ICE_ST_USE_TURN_PERM.patch
 	$(APPLY) $(SRC)/pjproject/0015-update-local-preference-for-peer-reflexive-candidate.patch
 	$(APPLY) $(SRC)/pjproject/0016-use-addrinfo-instead-CFHOST.patch
+	$(APPLY) $(SRC)/pjproject/0017-CVE-2020-15260.patch
+	$(APPLY) $(SRC)/pjproject/0018-CVE-2021-21375.patch
 ifdef HAVE_ANDROID
 	$(APPLY) $(SRC)/pjproject/0001-android.patch
 endif
-- 
GitLab