From e214f5c81b622cef14c4a29b2e8785e4752260fa Mon Sep 17 00:00:00 2001 From: George Joseph Date: Mon, 25 Aug 2025 07:56:27 -0600 Subject: [PATCH] pjproject: Update bundled to 2.15.1. This resolves a security issue where RTP ports weren't being released causing possible resource exhaustion issues. Resolves: #GHSA-557q-795j-wfx2 --- .../0000-configure-ssl-library-path.patch | 48 +++--- ...ck_between_transport_and_transaction.patch | 158 ++++++++++++++++++ third-party/pjproject/patches/config_site.h | 4 +- .../pjproject/pjproject-2.14.1.tar.bz2.md5 | 1 - .../pjproject/pjproject-2.15.1.tar.bz2.md5 | 1 + third-party/versions.mak | 2 +- 6 files changed, 186 insertions(+), 28 deletions(-) create mode 100644 third-party/pjproject/patches/0010-Avoid_deadlock_between_transport_and_transaction.patch delete mode 100644 third-party/pjproject/pjproject-2.14.1.tar.bz2.md5 create mode 100644 third-party/pjproject/pjproject-2.15.1.tar.bz2.md5 diff --git a/third-party/pjproject/patches/0000-configure-ssl-library-path.patch b/third-party/pjproject/patches/0000-configure-ssl-library-path.patch index c4dbb49e62..2967e72cf3 100644 --- a/third-party/pjproject/patches/0000-configure-ssl-library-path.patch +++ b/third-party/pjproject/patches/0000-configure-ssl-library-path.patch @@ -2,33 +2,33 @@ diff --git a/aconfigure b/aconfigure index d6f0e8809..9dcd46398 100755 --- a/aconfigure +++ b/aconfigure -@@ -8986,7 +8986,11 @@ else $as_nop - if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then - CFLAGS="$CFLAGS -I$with_ssl/include" - CPPFLAGS="$CPPFLAGS -I$with_ssl/include" -- LDFLAGS="$LDFLAGS -L$with_ssl/lib" -+ if test -d $with_ssl/lib; then -+ LDFLAGS="$LDFLAGS -L$with_ssl/lib" -+ else -+ LDFLAGS="$LDFLAGS -L$with_ssl" -+ fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using SSL prefix... $with_ssl" >&5 +@@ -9768,7 +9768,11 @@ + if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then + CFLAGS="$CFLAGS -I$with_ssl/include" + CPPFLAGS="$CPPFLAGS -I$with_ssl/include" +- LDFLAGS="$LDFLAGS -L$with_ssl/lib" ++ if test -d $with_ssl/lib; then ++ LDFLAGS="$LDFLAGS -L$with_ssl/lib" ++ else ++ LDFLAGS="$LDFLAGS -L$with_ssl" ++ fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using SSL prefix... $with_ssl" >&5 printf "%s\n" "Using SSL prefix... $with_ssl" >&6; } - fi + fi diff --git a/aconfigure.ac b/aconfigure.ac index 16b311045..849da81ab 100644 --- a/aconfigure.ac +++ b/aconfigure.ac -@@ -1838,7 +1838,11 @@ AC_ARG_ENABLE(ssl, - if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then - CFLAGS="$CFLAGS -I$with_ssl/include" - CPPFLAGS="$CPPFLAGS -I$with_ssl/include" -- LDFLAGS="$LDFLAGS -L$with_ssl/lib" -+ if test -d $with_ssl/lib; then -+ LDFLAGS="$LDFLAGS -L$with_ssl/lib" -+ else -+ LDFLAGS="$LDFLAGS -L$with_ssl" -+ fi - AC_MSG_RESULT([Using SSL prefix... $with_ssl]) - fi +@@ -2172,7 +2172,11 @@ + if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then + CFLAGS="$CFLAGS -I$with_ssl/include" + CPPFLAGS="$CPPFLAGS -I$with_ssl/include" +- LDFLAGS="$LDFLAGS -L$with_ssl/lib" ++ if test -d $with_ssl/lib; then ++ LDFLAGS="$LDFLAGS -L$with_ssl/lib" ++ else ++ LDFLAGS="$LDFLAGS -L$with_ssl" ++ fi + AC_MSG_RESULT([Using SSL prefix... $with_ssl]) + fi diff --git a/third-party/pjproject/patches/0010-Avoid_deadlock_between_transport_and_transaction.patch b/third-party/pjproject/patches/0010-Avoid_deadlock_between_transport_and_transaction.patch new file mode 100644 index 0000000000..e23af92b84 --- /dev/null +++ b/third-party/pjproject/patches/0010-Avoid_deadlock_between_transport_and_transaction.patch @@ -0,0 +1,158 @@ +From edde06f261ac807a89a6086b7f03460867675f95 Mon Sep 17 00:00:00 2001 +From: Nanang Izzuddin +Date: Tue, 1 Jul 2025 15:13:36 +0700 +Subject: [PATCH] Avoid deadlock between transport and transaction (#4453) + +--- + pjsip/include/pjsip/sip_transaction.h | 1 + + pjsip/src/pjsip/sip_transaction.c | 101 ++++++++++++++++++++++---- + 2 files changed, 88 insertions(+), 14 deletions(-) + +diff --git a/pjsip/include/pjsip/sip_transaction.h b/pjsip/include/pjsip/sip_transaction.h +index 72d4bc81c5..5f28b2d69c 100644 +--- a/pjsip/include/pjsip/sip_transaction.h ++++ b/pjsip/include/pjsip/sip_transaction.h +@@ -141,6 +141,7 @@ struct pjsip_transaction + int retransmit_count;/**< Retransmission count. */ + pj_timer_entry retransmit_timer;/**< Retransmit timer. */ + pj_timer_entry timeout_timer; /**< Timeout timer. */ ++ pj_timer_entry misc_timer; /**< Miscellaneous timer. */ + + /** Module specific data. */ + void *mod_data[PJSIP_MAX_MODULE]; +diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c +index 4335f11ff5..31dbaaab6e 100644 +--- a/pjsip/src/pjsip/sip_transaction.c ++++ b/pjsip/src/pjsip/sip_transaction.c +@@ -140,6 +140,7 @@ static int max_retrans_count = -1; + #define TRANSPORT_ERR_TIMER 3 + #define TRANSPORT_DISC_TIMER 4 + #define TERMINATE_TIMER 5 ++#define TRANSPORT_CB_TIMER 6 + + /* Flags for tsx_set_state() */ + enum +@@ -2265,23 +2266,21 @@ static void send_msg_callback( pjsip_send_state *send_state, + } + + +-/* Transport callback. */ +-static void transport_callback(void *token, pjsip_tx_data *tdata, +- pj_ssize_t sent) +-{ +- pjsip_transaction *tsx = (pjsip_transaction*) token; ++/* Transport callback parameter. */ ++struct tp_cb_param { ++ pjsip_transaction* tsx; ++ pjsip_tx_data* tdata; ++ pj_ssize_t sent; ++}; + +- /* Check if the transaction layer has been shutdown. */ +- if (mod_tsx_layer.mod.id < 0) +- return; + +- /* In other circumstances, locking tsx->grp_lock AFTER transport mutex +- * will introduce deadlock if another thread is currently sending a +- * SIP message to the transport. But this should be safe as there should +- * be no way this callback could be called while another thread is +- * sending a message. +- */ ++/* Transport callback actual implementation. */ ++static void transport_callback_impl(pjsip_transaction *tsx, ++ pjsip_tx_data* tdata, ++ pj_ssize_t sent) ++{ + pj_grp_lock_acquire(tsx->grp_lock); ++ + tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT); + + if (sent > 0 || tsx->role == PJSIP_ROLE_UAS) { +@@ -2299,6 +2298,7 @@ static void transport_callback(void *token, pjsip_tx_data *tdata, + tsx_set_state( tsx, PJSIP_TSX_STATE_DESTROYED, + PJSIP_EVENT_UNKNOWN, NULL, 0 ); + pj_grp_lock_release(tsx->grp_lock); ++ pj_grp_lock_dec_ref(tsx->grp_lock); + return; + } + +@@ -2354,6 +2354,79 @@ static void transport_callback(void *token, pjsip_tx_data *tdata, + } + + ++/* Timer callback for transport callback. ++ * This is currently only used to avoid deadlock due to inversed locking order ++ * between transport and transaction. ++ */ ++static void tsx_misc_timer_callback(pj_timer_heap_t *theap, ++ pj_timer_entry *entry) ++{ ++ PJ_UNUSED_ARG(theap); ++ ++ if (entry->id == TRANSPORT_CB_TIMER) { ++ struct tp_cb_param* param = (struct tp_cb_param*)entry->user_data; ++ ++ /* Check if the transaction layer has been shutdown. */ ++ if (mod_tsx_layer.mod.id >= 0) { ++ /* Call transport callback implementation */ ++ transport_callback_impl(param->tsx, param->tdata, param->sent); ++ } ++ ++ /* Release tdata */ ++ pjsip_tx_data_dec_ref(param->tdata); ++ } ++} ++ ++ ++/* Transport callback. */ ++static void transport_callback(void *token, pjsip_tx_data *tdata, ++ pj_ssize_t sent) ++{ ++ pjsip_transaction *tsx = (pjsip_transaction*) token; ++ pj_status_t status; ++ ++ /* Check if the transaction layer has been shutdown. */ ++ if (mod_tsx_layer.mod.id < 0) ++ return; ++ ++ /* In other circumstances, locking tsx->grp_lock AFTER transport mutex ++ * will introduce deadlock if another thread is currently sending a ++ * SIP message to the transport. But this should be safe as there should ++ * be no way this callback could be called while another thread is ++ * sending a message. ++ */ ++ // Deadlock does happen, see #4453. ++ // So now, to avoid deadlock, we'll try to acquire the group lock first, ++ // and if it fails, we'll schedule the processing via timer. ++ status = pj_grp_lock_tryacquire(tsx->grp_lock); ++ if (status != PJ_SUCCESS) { ++ pj_time_val delay = { 0, 0 }; ++ struct tp_cb_param *param = NULL; ++ ++ lock_timer(tsx); ++ tsx_cancel_timer(tsx, &tsx->misc_timer); ++ ++ /* Increment tdata ref count to avoid premature destruction. ++ * Note that tsx ref count is already handled by tsx_schedule_timer(). ++ */ ++ pjsip_tx_data_add_ref(tdata); ++ ++ param = PJ_POOL_ZALLOC_T(tsx->pool, struct tp_cb_param); ++ param->sent = sent; ++ param->tdata = tdata; ++ param->tsx = tsx; ++ pj_timer_entry_init(&tsx->misc_timer, TIMER_INACTIVE, param, ++ &tsx_misc_timer_callback); ++ tsx_schedule_timer(tsx, &tsx->misc_timer, &delay, TRANSPORT_CB_TIMER); ++ unlock_timer(tsx); ++ return; ++ } ++ ++ transport_callback_impl(tsx, tdata, sent); ++ pj_grp_lock_release(tsx->grp_lock); ++} ++ ++ + /* + * Callback when transport state changes. + */ diff --git a/third-party/pjproject/patches/config_site.h b/third-party/pjproject/patches/config_site.h index 0492b04812..4c36c78484 100644 --- a/third-party/pjproject/patches/config_site.h +++ b/third-party/pjproject/patches/config_site.h @@ -84,9 +84,9 @@ #define PJ_ICE_MAX_CHECKS (PJ_ICE_MAX_CAND * PJ_ICE_MAX_CAND) /* Increase limits to allow more formats */ -#define PJMEDIA_MAX_SDP_FMT 64 +#define PJMEDIA_MAX_SDP_FMT 72 #define PJMEDIA_MAX_SDP_BANDW 4 -#define PJMEDIA_MAX_SDP_ATTR (PJMEDIA_MAX_SDP_FMT*3 + 4) +#define PJMEDIA_MAX_SDP_ATTR (PJMEDIA_MAX_SDP_FMT*6 + 4) #define PJMEDIA_MAX_SDP_MEDIA 16 /* diff --git a/third-party/pjproject/pjproject-2.14.1.tar.bz2.md5 b/third-party/pjproject/pjproject-2.14.1.tar.bz2.md5 deleted file mode 100644 index 080e2a10d6..0000000000 --- a/third-party/pjproject/pjproject-2.14.1.tar.bz2.md5 +++ /dev/null @@ -1 +0,0 @@ -de9feca3e4816b1535f63f9d23c7b45b pjproject-2.14.1.tar.bz2 diff --git a/third-party/pjproject/pjproject-2.15.1.tar.bz2.md5 b/third-party/pjproject/pjproject-2.15.1.tar.bz2.md5 new file mode 100644 index 0000000000..9542ae1f2c --- /dev/null +++ b/third-party/pjproject/pjproject-2.15.1.tar.bz2.md5 @@ -0,0 +1 @@ +6b4b34c14d39224d3342d368f5abbad4 pjproject-2.15.1.tar.bz2 diff --git a/third-party/versions.mak b/third-party/versions.mak index 8756a090c1..71b64e55eb 100644 --- a/third-party/versions.mak +++ b/third-party/versions.mak @@ -2,5 +2,5 @@ # configure script so it must follow 'shell' # syntax as well as 'make' syntax. JANSSON_VERSION=2.14 -PJPROJECT_VERSION=2.14.1 +PJPROJECT_VERSION=2.15.1 LIBJWT_VERSION=1.15.3