neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/28210 )
Change subject: fix rare segfault in MGCP client handling ......................................................................
fix rare segfault in MGCP client handling
Add missing conn->assignment.created_ci_for_msc to gscon_forget_mgw_endpoint_ci().
Before this patch, when assignment.created_ci_for_msc lingers after a DLCX, it can cause a use-after-free on assignment_reset(). Possible scenario is rx BSSMAP Clear Cmd during ongoing Assignment.
In assignment_reset(), locally cache the ci pointer, because gscon_forget_mgw_endpoint_ci() now NULLs created_ci_for_msc.
Related: OS#5572 Change-Id: If89610020f47fd6517081dd11b83911b043bd0f1 --- M src/osmo-bsc/assignment_fsm.c M src/osmo-bsc/bsc_subscr_conn_fsm.c 2 files changed, 8 insertions(+), 2 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/10/28210/1
diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c index 7deca65..a0d008d 100644 --- a/src/osmo-bsc/assignment_fsm.c +++ b/src/osmo-bsc/assignment_fsm.c @@ -128,10 +128,13 @@ }
if (conn->assignment.created_ci_for_msc) { - gscon_forget_mgw_endpoint_ci(conn, conn->assignment.created_ci_for_msc); + /* Store ci pointer locally, because gscon_forget_mgw_endpoint_ci() NULLs + * conn->assignment.created_ci_for_msc. */ + struct osmo_mgcpc_ep_ci *ci = conn->assignment.created_ci_for_msc; + gscon_forget_mgw_endpoint_ci(conn, ci); /* If this is the last endpoint released, the mgw_endpoint_fsm will terminate and tell * the gscon about it. */ - osmo_mgcpc_ep_ci_dlcx(conn->assignment.created_ci_for_msc); + osmo_mgcpc_ep_ci_dlcx(ci); }
conn->assignment = (struct assignment_fsm_data){ diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c index 54d3975..9af28c7 100644 --- a/src/osmo-bsc/bsc_subscr_conn_fsm.c +++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c @@ -955,6 +955,9 @@
if (conn->user_plane.mgw_endpoint_ci_msc == ci) conn->user_plane.mgw_endpoint_ci_msc = NULL; + + if (conn->assignment.created_ci_for_msc == ci) + conn->assignment.created_ci_for_msc = NULL; }
static void gscon_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data)