From 224a3236cbeaeb06a897cb3beab8c3a0c3d5903f Mon Sep 17 00:00:00 2001 From: Razvan Crainea Date: Mon, 15 Jan 2024 15:35:03 +0200 Subject: [PATCH] dialog: do not populate dst_leg on unmatched dlg Avoid chaning the dst_leg on unmatched dialogs, as this might lead to inconsistent states. A common pattern is to match a dialog in state 5, which would set a dst_leg, but then "invalidate" the dialog due to the bad state - proceeding to a next dialog would not set the dst_leg (as it was set by the previous match), leading to an invalid access in the second dialog. Credits go to NFON for reporting and providing valuable troubleshooting information --- modules/dialog/dlg_hash.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/dialog/dlg_hash.c b/modules/dialog/dlg_hash.c index dee16cdacca..a1f2a0b726f 100644 --- a/modules/dialog/dlg_hash.c +++ b/modules/dialog/dlg_hash.c @@ -819,6 +819,7 @@ struct dlg_cell* get_dlg( str *callid, str *ftag, str *ttag, struct dlg_cell *dlg; struct dlg_entry *d_entry; unsigned int h_entry; + unsigned int dst_leg_backup = *dst_leg; h_entry = dlg_hash(callid); d_entry = &(d_table->entries[h_entry]); @@ -844,12 +845,16 @@ struct dlg_cell* get_dlg( str *callid, str *ftag, str *ttag, dlg->legs[DLG_CALLER_LEG].contact.len); #endif if (match_dialog( dlg, callid, ftag, ttag, dir, dst_leg)==1) { - if (dlg->state==DLG_STATE_DELETED) + if (dlg->state==DLG_STATE_DELETED) { /* even if matched, skip the deleted dialogs as they may be a previous unsuccessful attempt of established call with the same callid and fromtag - like in auth/challenge case -bogdan */ + /* since this dialog is not considered matched, then the + * dst_leg should not be populated either */ + *dst_leg = dst_leg_backup; continue; + } DBG_REF(dlg, 1); dlg->ref++; dlg_unlock( d_table, d_entry);