1 From db3235953baa56d2fb0e276ca510fefca751643f Mon Sep 17 00:00:00 2001
2 From: Nanang Izzuddin <nanang@teluu.com>
3 Date: Mon, 21 Feb 2022 06:24:52 +0700
4 Subject: [PATCH] Merge pull request from GHSA-ffff-m5fm-qm62
6 * Update pjsip_ua_unregister_dlg():
7 - update the hash key if the dialog being unregistered is used as hash key.
8 - add an assertion check to make sure that the dlg_set to be removed is valid (can be found in the hash table).
10 * Change hash key string comparison method.
12 pjsip/src/pjsip/sip_ua_layer.c | 48 +++++++++++++++++++++++++++++-----
13 1 file changed, 42 insertions(+), 6 deletions(-)
15 --- a/pjsip/src/pjsip/sip_ua_layer.c
16 +++ b/pjsip/src/pjsip/sip_ua_layer.c
17 @@ -65,6 +65,9 @@ struct dlg_set
18 /* This is the buffer to store this entry in the hash table. */
19 pj_hash_entry_buf ht_entry;
21 + /* Entry key in the hash table */
24 /* List of dialog in this dialog set. */
25 struct dlg_set_head dlg_list;
27 @@ -321,6 +324,7 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl
28 * Create the dialog set and add this dialog to it.
30 dlg_set = alloc_dlgset_node();
31 + dlg_set->ht_key = dlg->local.info->tag;
32 pj_list_init(&dlg_set->dlg_list);
33 pj_list_push_back(&dlg_set->dlg_list, dlg);
35 @@ -328,8 +332,8 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl
37 /* Register the dialog set in the hash table. */
38 pj_hash_set_np_lower(mod_ua.dlg_table,
39 - dlg->local.info->tag.ptr,
40 - (unsigned)dlg->local.info->tag.slen,
41 + dlg_set->ht_key.ptr,
42 + (unsigned)dlg_set->ht_key.slen,
43 dlg->local.tag_hval, dlg_set->ht_entry,
46 @@ -339,14 +343,15 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl
47 struct dlg_set *dlg_set;
49 dlg_set = alloc_dlgset_node();
50 + dlg_set->ht_key = dlg->local.info->tag;
51 pj_list_init(&dlg_set->dlg_list);
52 pj_list_push_back(&dlg_set->dlg_list, dlg);
54 dlg->dlg_set = dlg_set;
56 pj_hash_set_np_lower(mod_ua.dlg_table,
57 - dlg->local.info->tag.ptr,
58 - (unsigned)dlg->local.info->tag.slen,
59 + dlg_set->ht_key.ptr,
60 + (unsigned)dlg_set->ht_key.slen,
61 dlg->local.tag_hval, dlg_set->ht_entry, dlg_set);
64 @@ -391,12 +396,43 @@ PJ_DEF(pj_status_t) pjsip_ua_unregister_
66 /* If dialog list is empty, remove the dialog set from the hash table. */
67 if (pj_list_empty(&dlg_set->dlg_list)) {
68 - pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg->local.info->tag.ptr,
69 - (unsigned)dlg->local.info->tag.slen,
71 + /* Verify that the dialog set is valid */
72 + pj_assert(pj_hash_get_lower(mod_ua.dlg_table, dlg_set->ht_key.ptr,
73 + (unsigned)dlg_set->ht_key.slen,
74 + &dlg->local.tag_hval) == dlg_set);
76 + pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg_set->ht_key.ptr,
77 + (unsigned)dlg_set->ht_key.slen,
78 dlg->local.tag_hval, NULL);
80 /* Return dlg_set to free nodes. */
81 pj_list_push_back(&mod_ua.free_dlgset_nodes, dlg_set);
83 + /* If the just unregistered dialog is being used as hash key,
84 + * reset the dlg_set entry with a new key (i.e: from the first dialog
87 + if (dlg_set->ht_key.ptr == dlg->local.info->tag.ptr &&
88 + dlg_set->ht_key.slen == dlg->local.info->tag.slen)
90 + pjsip_dialog* key_dlg = dlg_set->dlg_list.next;
92 + /* Verify that the old & new keys share the hash value */
93 + pj_assert(key_dlg->local.tag_hval == dlg->local.tag_hval);
95 + pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg_set->ht_key.ptr,
96 + (unsigned)dlg_set->ht_key.slen,
97 + dlg->local.tag_hval, NULL);
99 + dlg_set->ht_key = key_dlg->local.info->tag;
101 + pj_hash_set_np_lower(mod_ua.dlg_table,
102 + dlg_set->ht_key.ptr,
103 + (unsigned)dlg_set->ht_key.slen,
104 + key_dlg->local.tag_hval, dlg_set->ht_entry,
109 /* Unlock user agent. */