Merge pull request #753 from micmac1/openwrt-21.02-AST
[feed/telephony.git] / libs / pjproject / patches / 0171-dialog-set-free.patch
diff --git a/libs/pjproject/patches/0171-dialog-set-free.patch b/libs/pjproject/patches/0171-dialog-set-free.patch
new file mode 100644 (file)
index 0000000..d113117
--- /dev/null
@@ -0,0 +1,109 @@
+From db3235953baa56d2fb0e276ca510fefca751643f Mon Sep 17 00:00:00 2001
+From: Nanang Izzuddin <nanang@teluu.com>
+Date: Mon, 21 Feb 2022 06:24:52 +0700
+Subject: [PATCH] Merge pull request from GHSA-ffff-m5fm-qm62
+
+* Update pjsip_ua_unregister_dlg():
+- update the hash key if the dialog being unregistered is used as hash key.
+- add an assertion check to make sure that the dlg_set to be removed is valid (can be found in the hash table).
+
+* Change hash key string comparison method.
+---
+ pjsip/src/pjsip/sip_ua_layer.c | 48 +++++++++++++++++++++++++++++-----
+ 1 file changed, 42 insertions(+), 6 deletions(-)
+
+--- a/pjsip/src/pjsip/sip_ua_layer.c
++++ b/pjsip/src/pjsip/sip_ua_layer.c
+@@ -65,6 +65,9 @@ struct dlg_set
+     /* This is the buffer to store this entry in the hash table. */
+     pj_hash_entry_buf ht_entry;
++    /* Entry key in the hash table */
++    pj_str_t ht_key;
++
+     /* List of dialog in this dialog set. */
+     struct dlg_set_head  dlg_list;
+ };
+@@ -321,6 +324,7 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl
+            * Create the dialog set and add this dialog to it.
+            */
+           dlg_set = alloc_dlgset_node();
++          dlg_set->ht_key = dlg->local.info->tag;
+           pj_list_init(&dlg_set->dlg_list);
+           pj_list_push_back(&dlg_set->dlg_list, dlg);
+@@ -328,8 +332,8 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl
+           /* Register the dialog set in the hash table. */
+           pj_hash_set_np_lower(mod_ua.dlg_table, 
+-                               dlg->local.info->tag.ptr,
+-                                 (unsigned)dlg->local.info->tag.slen,
++                               dlg_set->ht_key.ptr,
++                                 (unsigned)dlg_set->ht_key.slen,
+                                dlg->local.tag_hval, dlg_set->ht_entry,
+                                  dlg_set);
+       }
+@@ -339,14 +343,15 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl
+       struct dlg_set *dlg_set;
+       dlg_set = alloc_dlgset_node();
++      dlg_set->ht_key = dlg->local.info->tag;
+       pj_list_init(&dlg_set->dlg_list);
+       pj_list_push_back(&dlg_set->dlg_list, dlg);
+       dlg->dlg_set = dlg_set;
+       pj_hash_set_np_lower(mod_ua.dlg_table, 
+-                           dlg->local.info->tag.ptr,
+-                             (unsigned)dlg->local.info->tag.slen,
++                           dlg_set->ht_key.ptr,
++                             (unsigned)dlg_set->ht_key.slen,
+                            dlg->local.tag_hval, dlg_set->ht_entry, dlg_set);
+     }
+@@ -391,12 +396,43 @@ PJ_DEF(pj_status_t) pjsip_ua_unregister_
+     /* If dialog list is empty, remove the dialog set from the hash table. */
+     if (pj_list_empty(&dlg_set->dlg_list)) {
+-      pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg->local.info->tag.ptr,
+-                        (unsigned)dlg->local.info->tag.slen, 
++
++      /* Verify that the dialog set is valid */
++      pj_assert(pj_hash_get_lower(mod_ua.dlg_table, dlg_set->ht_key.ptr,
++                                  (unsigned)dlg_set->ht_key.slen,
++                                  &dlg->local.tag_hval) == dlg_set);
++
++      pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg_set->ht_key.ptr,
++                        (unsigned)dlg_set->ht_key.slen,
+                         dlg->local.tag_hval, NULL);
+       /* Return dlg_set to free nodes. */
+       pj_list_push_back(&mod_ua.free_dlgset_nodes, dlg_set);
++    } else {
++      /* If the just unregistered dialog is being used as hash key,
++       * reset the dlg_set entry with a new key (i.e: from the first dialog
++       * in dlg_set).
++       */
++      if (dlg_set->ht_key.ptr  == dlg->local.info->tag.ptr &&
++          dlg_set->ht_key.slen == dlg->local.info->tag.slen)
++      {
++          pjsip_dialog* key_dlg = dlg_set->dlg_list.next;
++
++          /* Verify that the old & new keys share the hash value */
++          pj_assert(key_dlg->local.tag_hval == dlg->local.tag_hval);
++
++          pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg_set->ht_key.ptr,
++                            (unsigned)dlg_set->ht_key.slen,
++                            dlg->local.tag_hval, NULL);
++
++          dlg_set->ht_key = key_dlg->local.info->tag;
++
++          pj_hash_set_np_lower(mod_ua.dlg_table,
++                               dlg_set->ht_key.ptr,
++                               (unsigned)dlg_set->ht_key.slen,
++                               key_dlg->local.tag_hval, dlg_set->ht_entry,
++                               dlg_set);
++      }
+     }
+     /* Unlock user agent. */