Skip to content

Commit db32359

Browse files
authored
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.
1 parent 9b37e58 commit db32359

File tree

1 file changed

+42
-6
lines changed

1 file changed

+42
-6
lines changed

Diff for: pjsip/src/pjsip/sip_ua_layer.c

+42-6
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ struct dlg_set
6565
/* This is the buffer to store this entry in the hash table. */
6666
pj_hash_entry_buf ht_entry;
6767

68+
/* Entry key in the hash table */
69+
pj_str_t ht_key;
70+
6871
/* List of dialog in this dialog set. */
6972
struct dlg_set_head dlg_list;
7073
};
@@ -327,15 +330,16 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dlg( pjsip_user_agent *ua,
327330
* Create the dialog set and add this dialog to it.
328331
*/
329332
dlg_set = alloc_dlgset_node();
333+
dlg_set->ht_key = dlg->local.info->tag;
330334
pj_list_init(&dlg_set->dlg_list);
331335
pj_list_push_back(&dlg_set->dlg_list, dlg);
332336

333337
dlg->dlg_set = dlg_set;
334338

335339
/* Register the dialog set in the hash table. */
336340
pj_hash_set_np_lower(mod_ua.dlg_table,
337-
dlg->local.info->tag.ptr,
338-
(unsigned)dlg->local.info->tag.slen,
341+
dlg_set->ht_key.ptr,
342+
(unsigned)dlg_set->ht_key.slen,
339343
dlg->local.tag_hval, dlg_set->ht_entry,
340344
dlg_set);
341345
}
@@ -345,14 +349,15 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dlg( pjsip_user_agent *ua,
345349
struct dlg_set *dlg_set;
346350

347351
dlg_set = alloc_dlgset_node();
352+
dlg_set->ht_key = dlg->local.info->tag;
348353
pj_list_init(&dlg_set->dlg_list);
349354
pj_list_push_back(&dlg_set->dlg_list, dlg);
350355

351356
dlg->dlg_set = dlg_set;
352357

353358
pj_hash_set_np_lower(mod_ua.dlg_table,
354-
dlg->local.info->tag.ptr,
355-
(unsigned)dlg->local.info->tag.slen,
359+
dlg_set->ht_key.ptr,
360+
(unsigned)dlg_set->ht_key.slen,
356361
dlg->local.tag_hval, dlg_set->ht_entry, dlg_set);
357362
}
358363

@@ -397,12 +402,43 @@ PJ_DEF(pj_status_t) pjsip_ua_unregister_dlg( pjsip_user_agent *ua,
397402

398403
/* If dialog list is empty, remove the dialog set from the hash table. */
399404
if (pj_list_empty(&dlg_set->dlg_list)) {
400-
pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg->local.info->tag.ptr,
401-
(unsigned)dlg->local.info->tag.slen,
405+
406+
/* Verify that the dialog set is valid */
407+
pj_assert(pj_hash_get_lower(mod_ua.dlg_table, dlg_set->ht_key.ptr,
408+
(unsigned)dlg_set->ht_key.slen,
409+
&dlg->local.tag_hval) == dlg_set);
410+
411+
pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg_set->ht_key.ptr,
412+
(unsigned)dlg_set->ht_key.slen,
402413
dlg->local.tag_hval, NULL);
403414

404415
/* Return dlg_set to free nodes. */
405416
pj_list_push_back(&mod_ua.free_dlgset_nodes, dlg_set);
417+
} else {
418+
/* If the just unregistered dialog is being used as hash key,
419+
* reset the dlg_set entry with a new key (i.e: from the first dialog
420+
* in dlg_set).
421+
*/
422+
if (dlg_set->ht_key.ptr == dlg->local.info->tag.ptr &&
423+
dlg_set->ht_key.slen == dlg->local.info->tag.slen)
424+
{
425+
pjsip_dialog* key_dlg = dlg_set->dlg_list.next;
426+
427+
/* Verify that the old & new keys share the hash value */
428+
pj_assert(key_dlg->local.tag_hval == dlg->local.tag_hval);
429+
430+
pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg_set->ht_key.ptr,
431+
(unsigned)dlg_set->ht_key.slen,
432+
dlg->local.tag_hval, NULL);
433+
434+
dlg_set->ht_key = key_dlg->local.info->tag;
435+
436+
pj_hash_set_np_lower(mod_ua.dlg_table,
437+
dlg_set->ht_key.ptr,
438+
(unsigned)dlg_set->ht_key.slen,
439+
key_dlg->local.tag_hval, dlg_set->ht_entry,
440+
dlg_set);
441+
}
406442
}
407443

408444
/* Unlock user agent. */

0 commit comments

Comments
 (0)