From 54ad579b30429084b449b93b994114f88301907f Mon Sep 17 00:00:00 2001 From: Sebastian Kemper Date: Sat, 31 Jul 2021 11:24:10 +0200 Subject: [PATCH] pjproject: sync patches with asterisk 18.5.1 Signed-off-by: Sebastian Kemper --- libs/pjproject/Makefile | 2 +- ...ip-unsupported-digest-algorithm-2408.patch | 201 ++++++++++++++++++ .../patches/0100-fix-double-stun-free.patch | 78 +++++++ .../0110-tls-parent-listener-destroyed.patch | 162 ++++++++++++++ 4 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 libs/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch create mode 100644 libs/pjproject/patches/0100-fix-double-stun-free.patch create mode 100644 libs/pjproject/patches/0110-tls-parent-listener-destroyed.patch diff --git a/libs/pjproject/Makefile b/libs/pjproject/Makefile index a52391d..2646500 100644 --- a/libs/pjproject/Makefile +++ b/libs/pjproject/Makefile @@ -11,7 +11,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=pjproject PKG_VERSION:=2.10 -PKG_RELEASE:=3 +PKG_RELEASE:=4 # download "vX.Y.tar.gz" as "pjproject-vX.Y.tar.gz" PKG_SOURCE_URL_FILE:=$(PKG_VERSION).tar.gz diff --git a/libs/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch b/libs/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch new file mode 100644 index 0000000..c779f67 --- /dev/null +++ b/libs/pjproject/patches/0090-Skip-unsupported-digest-algorithm-2408.patch @@ -0,0 +1,201 @@ +From bdbeb7c4b2b11efc2e59f5dee7aa4360a2bc9fff Mon Sep 17 00:00:00 2001 +From: sauwming +Date: Thu, 22 Apr 2021 14:03:28 +0800 +Subject: [PATCH 90/90] Skip unsupported digest algorithm (#2408) + +Co-authored-by: Nanang Izzuddin +--- + pjsip/src/pjsip/sip_auth_client.c | 32 +++++-- + tests/pjsua/scripts-sipp/uas-auth-two-algo.py | 7 ++ + .../pjsua/scripts-sipp/uas-auth-two-algo.xml | 83 +++++++++++++++++++ + 3 files changed, 117 insertions(+), 5 deletions(-) + create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.py + create mode 100644 tests/pjsua/scripts-sipp/uas-auth-two-algo.xml + +--- a/pjsip/src/pjsip/sip_auth_client.c ++++ b/pjsip/src/pjsip/sip_auth_client.c +@@ -1042,7 +1042,7 @@ static pj_status_t process_auth( pj_pool + pjsip_hdr *hdr; + pj_status_t status; + +- /* See if we have sent authorization header for this realm */ ++ /* See if we have sent authorization header for this realm (and scheme) */ + hdr = tdata->msg->hdr.next; + while (hdr != &tdata->msg->hdr) { + if ((hchal->type == PJSIP_H_WWW_AUTHENTICATE && +@@ -1052,7 +1052,8 @@ static pj_status_t process_auth( pj_pool + { + sent_auth = (pjsip_authorization_hdr*) hdr; + if (pj_stricmp(&hchal->challenge.common.realm, +- &sent_auth->credential.common.realm )==0) ++ &sent_auth->credential.common.realm)==0 && ++ pj_stricmp(&hchal->scheme, &sent_auth->scheme)==0) + { + /* If this authorization has empty response, remove it. */ + if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 && +@@ -1062,6 +1063,14 @@ static pj_status_t process_auth( pj_pool + hdr = hdr->next; + pj_list_erase(sent_auth); + continue; ++ } else ++ if (pj_stricmp(&sent_auth->scheme, &pjsip_DIGEST_STR)==0 && ++ pj_stricmp(&sent_auth->credential.digest.algorithm, ++ &hchal->challenge.digest.algorithm)!=0) ++ { ++ /* Same 'digest' scheme but different algo */ ++ hdr = hdr->next; ++ continue; + } else { + /* Found previous authorization attempt */ + break; +@@ -1155,9 +1164,10 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini + { + pjsip_tx_data *tdata; + const pjsip_hdr *hdr; +- unsigned chal_cnt; ++ unsigned chal_cnt, auth_cnt; + pjsip_via_hdr *via; + pj_status_t status; ++ pj_status_t last_auth_err; + + PJ_ASSERT_RETURN(sess && rdata && old_request && new_request, + PJ_EINVAL); +@@ -1178,6 +1188,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini + */ + hdr = rdata->msg_info.msg->hdr.next; + chal_cnt = 0; ++ auth_cnt = 0; ++ last_auth_err = PJSIP_EAUTHNOAUTH; + while (hdr != &rdata->msg_info.msg->hdr) { + pjsip_cached_auth *cached_auth; + const pjsip_www_authenticate_hdr *hchal; +@@ -1222,8 +1234,13 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini + */ + status = process_auth(tdata->pool, hchal, tdata->msg->line.req.uri, + tdata, sess, cached_auth, &hauth); +- if (status != PJ_SUCCESS) +- return status; ++ if (status != PJ_SUCCESS) { ++ last_auth_err = status; ++ ++ /* Process next header. */ ++ hdr = hdr->next; ++ continue; ++ } + + if (pj_pool_get_used_size(cached_auth->pool) > + PJSIP_AUTH_CACHED_POOL_MAX_SIZE) +@@ -1236,12 +1253,17 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reini + + /* Process next header. */ + hdr = hdr->next; ++ auth_cnt++; + } + + /* Check if challenge is present */ + if (chal_cnt == 0) + return PJSIP_EAUTHNOCHAL; + ++ /* Check if any authorization header has been created */ ++ if (auth_cnt == 0) ++ return last_auth_err; ++ + /* Remove branch param in Via header. */ + via = (pjsip_via_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); + via->branch_param.slen = 0; +--- /dev/null ++++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.py +@@ -0,0 +1,7 @@ ++# $Id$ ++# ++import inc_const as const ++ ++PJSUA = ["--null-audio --max-calls=1 --id=sip:a@localhost --username=a --realm=* --registrar=$SIPP_URI"] ++ ++PJSUA_EXPECTS = [[0, "registration success", ""]] +--- /dev/null ++++ b/tests/pjsua/scripts-sipp/uas-auth-two-algo.xml +@@ -0,0 +1,83 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --git a/libs/pjproject/patches/0100-fix-double-stun-free.patch b/libs/pjproject/patches/0100-fix-double-stun-free.patch new file mode 100644 index 0000000..f1691b9 --- /dev/null +++ b/libs/pjproject/patches/0100-fix-double-stun-free.patch @@ -0,0 +1,78 @@ +commit f0ff5817d0647bdecd1ec99488db9378e304cf83 +Author: sauwming +Date: Mon May 17 09:56:27 2021 +0800 + + Fix double free of stun session (#2709) + +--- a/pjnath/include/pjnath/stun_session.h ++++ b/pjnath/include/pjnath/stun_session.h +@@ -341,6 +341,7 @@ struct pj_stun_tx_data + pj_pool_t *pool; /**< Pool. */ + pj_stun_session *sess; /**< The STUN session. */ + pj_stun_msg *msg; /**< The STUN message. */ ++ pj_bool_t is_destroying; /**< Is destroying? */ + + void *token; /**< The token. */ + +--- a/pjnath/src/pjnath/stun_session.c ++++ b/pjnath/src/pjnath/stun_session.c +@@ -167,16 +167,27 @@ static void tdata_on_destroy(void *arg) + { + pj_stun_tx_data *tdata = (pj_stun_tx_data*)arg; + ++ if (tdata->grp_lock) { ++ pj_grp_lock_dec_ref(tdata->sess->grp_lock); ++ } ++ + pj_pool_safe_release(&tdata->pool); + } + + static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force) + { +- TRACE_((THIS_FILE, "tdata %p destroy request, force=%d, tsx=%p", tdata, +- force, tdata->client_tsx)); ++ TRACE_((THIS_FILE, ++ "tdata %p destroy request, force=%d, tsx=%p, destroying=%d", ++ tdata, force, tdata->client_tsx, tdata->is_destroying)); ++ ++ /* Just return if destroy has been requested before */ ++ if (tdata->is_destroying) ++ return; + + /* STUN session may have been destroyed, except when tdata is cached. */ + ++ tdata->is_destroying = PJ_TRUE; ++ + if (tdata->res_timer.id != PJ_FALSE) { + pj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap, + &tdata->res_timer, PJ_FALSE); +@@ -189,7 +200,6 @@ static void destroy_tdata(pj_stun_tx_dat + pj_stun_client_tsx_set_data(tdata->client_tsx, NULL); + } + if (tdata->grp_lock) { +- pj_grp_lock_dec_ref(tdata->sess->grp_lock); + pj_grp_lock_dec_ref(tdata->grp_lock); + } else { + tdata_on_destroy(tdata); +@@ -200,11 +210,11 @@ static void destroy_tdata(pj_stun_tx_dat + /* "Probably" this is to absorb retransmission */ + pj_time_val delay = {0, 300}; + pj_stun_client_tsx_schedule_destroy(tdata->client_tsx, &delay); ++ tdata->is_destroying = PJ_FALSE; + + } else { + pj_list_erase(tdata); + if (tdata->grp_lock) { +- pj_grp_lock_dec_ref(tdata->sess->grp_lock); + pj_grp_lock_dec_ref(tdata->grp_lock); + } else { + tdata_on_destroy(tdata); +@@ -238,7 +248,7 @@ static void on_cache_timeout(pj_timer_he + sess = tdata->sess; + + pj_grp_lock_acquire(sess->grp_lock); +- if (sess->is_destroying) { ++ if (sess->is_destroying || tdata->is_destroying) { + pj_grp_lock_release(sess->grp_lock); + return; + } diff --git a/libs/pjproject/patches/0110-tls-parent-listener-destroyed.patch b/libs/pjproject/patches/0110-tls-parent-listener-destroyed.patch new file mode 100644 index 0000000..e496fe4 --- /dev/null +++ b/libs/pjproject/patches/0110-tls-parent-listener-destroyed.patch @@ -0,0 +1,162 @@ +From bb92c97ea512aa0ef316c9b2335c7d57b84dfc9a Mon Sep 17 00:00:00 2001 +From: Nanang Izzuddin +Date: Wed, 16 Jun 2021 12:12:35 +0700 +Subject: [PATCH 1/2] - Avoid SSL socket parent/listener getting destroyed + during handshake by increasing parent's reference count. - Add missing SSL + socket close when the newly accepted SSL socket is discarded in SIP TLS + transport. + +--- + pjlib/src/pj/ssl_sock_imp_common.c | 44 +++++++++++++++++++++-------- + pjsip/src/pjsip/sip_transport_tls.c | 23 ++++++++++++++- + 2 files changed, 55 insertions(+), 12 deletions(-) + +--- a/pjlib/src/pj/ssl_sock_imp_common.c ++++ b/pjlib/src/pj/ssl_sock_imp_common.c +@@ -224,6 +224,8 @@ static pj_bool_t on_handshake_complete(p + + /* Accepting */ + if (ssock->is_server) { ++ pj_bool_t ret = PJ_TRUE; ++ + if (status != PJ_SUCCESS) { + /* Handshake failed in accepting, destroy our self silently. */ + +@@ -241,6 +243,12 @@ static pj_bool_t on_handshake_complete(p + status); + } + ++ /* Decrement ref count of parent */ ++ if (ssock->parent->param.grp_lock) { ++ pj_grp_lock_dec_ref(ssock->parent->param.grp_lock); ++ ssock->parent = NULL; ++ } ++ + /* Originally, this is a workaround for ticket #985. However, + * a race condition may occur in multiple worker threads + * environment when we are destroying SSL objects while other +@@ -284,23 +292,29 @@ static pj_bool_t on_handshake_complete(p + + return PJ_FALSE; + } ++ + /* Notify application the newly accepted SSL socket */ + if (ssock->param.cb.on_accept_complete2) { +- pj_bool_t ret; + ret = (*ssock->param.cb.on_accept_complete2) + (ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr, + pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr), + status); +- if (ret == PJ_FALSE) +- return PJ_FALSE; + } else if (ssock->param.cb.on_accept_complete) { +- pj_bool_t ret; + ret = (*ssock->param.cb.on_accept_complete) + (ssock->parent, ssock, (pj_sockaddr_t*)&ssock->rem_addr, + pj_sockaddr_get_len((pj_sockaddr_t*)&ssock->rem_addr)); +- if (ret == PJ_FALSE) +- return PJ_FALSE; + } ++ ++ /* Decrement ref count of parent and reset parent (we don't need it ++ * anymore, right?). ++ */ ++ if (ssock->parent->param.grp_lock) { ++ pj_grp_lock_dec_ref(ssock->parent->param.grp_lock); ++ ssock->parent = NULL; ++ } ++ ++ if (ret == PJ_FALSE) ++ return PJ_FALSE; + } + + /* Connecting */ +@@ -864,9 +878,13 @@ static pj_bool_t asock_on_accept_complet + if (status != PJ_SUCCESS) + goto on_return; + ++ /* Set parent and add ref count (avoid parent destroy during handshake) */ ++ ssock->parent = ssock_parent; ++ if (ssock->parent->param.grp_lock) ++ pj_grp_lock_add_ref(ssock->parent->param.grp_lock); ++ + /* Update new SSL socket attributes */ + ssock->sock = newsock; +- ssock->parent = ssock_parent; + ssock->is_server = PJ_TRUE; + if (ssock_parent->cert) { + status = pj_ssl_sock_set_certificate(ssock, ssock->pool, +@@ -913,16 +931,20 @@ static pj_bool_t asock_on_accept_complet + ssock->asock_rbuf = (void**)pj_pool_calloc(ssock->pool, + ssock->param.async_cnt, + sizeof(void*)); +- if (!ssock->asock_rbuf) +- return PJ_ENOMEM; ++ if (!ssock->asock_rbuf) { ++ status = PJ_ENOMEM; ++ goto on_return; ++ } + + for (i = 0; iparam.async_cnt; ++i) { +- ssock->asock_rbuf[i] = (void*) pj_pool_alloc( ++ ssock->asock_rbuf[i] = (void*) pj_pool_alloc( + ssock->pool, + ssock->param.read_buffer_size + + sizeof(read_data_t*)); +- if (!ssock->asock_rbuf[i]) +- return PJ_ENOMEM; ++ if (!ssock->asock_rbuf[i]) { ++ status = PJ_ENOMEM; ++ goto on_return; ++ } + } + + /* Create active socket */ +--- a/pjsip/src/pjsip/sip_transport_tls.c ++++ b/pjsip/src/pjsip/sip_transport_tls.c +@@ -1325,9 +1325,26 @@ static pj_bool_t on_accept_complete2(pj_ + PJ_UNUSED_ARG(src_addr_len); + + listener = (struct tls_listener*) pj_ssl_sock_get_user_data(ssock); ++ if (!listener) { ++ /* Listener already destroyed, e.g: after TCP accept but before SSL ++ * handshake is completed. ++ */ ++ if (new_ssock && accept_status == PJ_SUCCESS) { ++ /* Close the SSL socket if the accept op is successful */ ++ PJ_LOG(4,(THIS_FILE, ++ "Incoming TLS connection from %s (sock=%d) is discarded " ++ "because listener is already destroyed", ++ pj_sockaddr_print(src_addr, addr, sizeof(addr), 3), ++ new_ssock)); ++ ++ pj_ssl_sock_close(new_ssock); ++ } ++ ++ return PJ_FALSE; ++ } + + if (accept_status != PJ_SUCCESS) { +- if (listener && listener->tls_setting.on_accept_fail_cb) { ++ if (listener->tls_setting.on_accept_fail_cb) { + pjsip_tls_on_accept_fail_param param; + pj_ssl_sock_info ssi; + +@@ -1350,6 +1367,8 @@ static pj_bool_t on_accept_complete2(pj_ + PJ_ASSERT_RETURN(new_ssock, PJ_TRUE); + + if (!listener->is_registered) { ++ pj_ssl_sock_close(new_ssock); ++ + if (listener->tls_setting.on_accept_fail_cb) { + pjsip_tls_on_accept_fail_param param; + pj_bzero(¶m, sizeof(param)); +@@ -1401,6 +1420,8 @@ static pj_bool_t on_accept_complete2(pj_ + ssl_info.grp_lock, &tls); + + if (status != PJ_SUCCESS) { ++ pj_ssl_sock_close(new_ssock); ++ + if (listener->tls_setting.on_accept_fail_cb) { + pjsip_tls_on_accept_fail_param param; + pj_bzero(¶m, sizeof(param)); -- 2.30.2