fix segfault on MGCP timeout

bisect shows that the segfault was introduced by using the MGCP client
pool:

 e62af4d46a is the first bad commit
 Author: Pau Espin Pedrol <pespin@sysmocom.de>
    Introduce support for libosmo-mgcp-client MGW pooling
    Change-Id I371dc773b58788ee21037dc25d77f556c89c6b61

The segfault:

 20230117224550365 DLMGCP DEBUG MGCP_CONN(to-HNB)[0x612000003ca0]{ST_CRCX_RESP}: Timeout of T1 (fsm.c:317)
 [...]
 20230117224550366 DLMGCP DEBUG mgw-endp(mgw-fsm-14429752-0)[0x612000003b20]{WAIT_MGW_RESPONSE}: Deallocated (fsm.c:568)
 20230117224550366 DMGW DEBUG mgw(mgw-fsm-14429752-0)[0x612000003820]{MGW_ST_CRCX_HNB}: Received Event MGW_EV_MGCP_TERM (mgcp_client_endpoint_fsm.c:869)
 =================================================================
 ==255699==ERROR: AddressSanitizer: heap-use-after-free on address 0x62b000000260 at pc 0x7f282a6ee143 bp 0x7fff0d9bcae0 sp 0x7fff0d9bcad8
 READ of size 8 at 0x62b000000260 thread T0
     #0 0x7f282a6ee142 in osmo_mgcpc_ep_client ../../../../src/osmo-mgw/src/libosmo-mgcp-client/mgcp_client_endpoint_fsm.c:223
     #1 0x55e2a84f1889 in mgw_fsm_allstate_action ../../../../src/osmo-hnbgw/src/osmo-hnbgw/mgw_fsm.c:504
     #2 0x7f2829d50c56 in _osmo_fsm_inst_dispatch ../../../src/libosmocore/src/fsm.c:863
     #3 0x7f2829d55a08 in _osmo_fsm_inst_term ../../../src/libosmocore/src/fsm.c:962
     #4 0x7f282a72679a in osmo_mgcpc_ep_fsm_check_state_chg_after_response ../../../../src/osmo-mgw/src/libosmo-mgcp-client/mgcp_client_endpoint_fsm.c:869
     #5 0x7f282a6f1869 in on_failure ../../../../src/osmo-mgw/src/libosmo-mgcp-client/mgcp_client_endpoint_fsm.c:414
     #6 0x7f282a727ac6 in osmo_mgcpc_ep_fsm_handle_ci_events ../../../../src/osmo-mgw/src/libosmo-mgcp-client/mgcp_client_endpoint_fsm.c:935
 [...]

When a CRCX times out, MGCP_CONN fsm terminates (libosmo-mgcp-client).
In turn the parent mgw-endp fsm terminates (libosmo-mgcp-client).
This generates an MGW_EV_MGCP_TERM event to the mgw_fsm (osmo-ttcn3-hacks).
This attempts to retrieve a pointer from mgw_fsm state:
mgw_fsm_priv->mgcpc_ep->mgcp_client
where the middle one, mgcpc_ep, is the 'mgw-endp' that already deallocated above.

To fix, add to /osmo-hnbgw/mgw_fsm.c a separate pointer to the
mgcp_client, to call mgcp_client_pool_put() on it. Do not use mgcpc_ep
to get the mgcp_client, because mgcpc_ep deallocates independently.

Related: OS#5862
Change-Id: I460d7249f4fc7edcfd94f6084fc8f933b491520c
This commit is contained in:
Neels Hofmeyr 2023-01-17 23:27:03 +01:00
parent 9bc7649b95
commit 28619961a9
1 changed files with 9 additions and 8 deletions

View File

@ -115,6 +115,7 @@ struct mgw_fsm_priv {
struct osmo_prim_hdr *ranap_rab_ass_resp_oph;
/* MGW context */
struct mgcp_client *mgcpc;
struct osmo_mgcpc_ep *mgcpc_ep;
struct osmo_mgcpc_ep_ci *mgcpc_ep_ci_hnb;
struct osmo_mgcpc_ep_ci *mgcpc_ep_ci_msc;
@ -141,7 +142,6 @@ static void mgw_fsm_crcx_hnb_onenter(struct osmo_fsm_inst *fi, uint32_t prev_sta
RANAP_RAB_AssignmentRequestIEs_t *ies;
const char *epname;
struct mgcp_conn_peer mgw_info;
struct mgcp_client *mgcp_client;
int rc;
LOGPFSML(fi, LOGL_DEBUG, "RAB-AssignmentRequest received, creating HNB side call-leg on MGW...\n");
@ -173,16 +173,16 @@ static void mgw_fsm_crcx_hnb_onenter(struct osmo_fsm_inst *fi, uint32_t prev_sta
mgw_info.codecs[0] = CODEC_IUFP;
mgw_info.codecs_len = 1;
mgcp_client = mgcp_client_pool_get(map->hnb_ctx->gw->mgw_pool);
if (!mgcp_client) {
mgw_fsm_priv->mgcpc = mgcp_client_pool_get(map->hnb_ctx->gw->mgw_pool);
if (!mgw_fsm_priv->mgcpc) {
LOGPFSML(fi, LOGL_ERROR,
"cannot ensure MGW endpoint -- no MGW configured, check configuration!\n");
osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0);
return;
}
epname = mgcp_client_rtpbridge_wildcard(mgcp_client);
epname = mgcp_client_rtpbridge_wildcard(mgw_fsm_priv->mgcpc);
mgw_fsm_priv->mgcpc_ep =
osmo_mgcpc_ep_alloc(fi, MGW_EV_MGCP_TERM, mgcp_client, mgw_fsm_T_defs, fi->id, "%s", epname);
osmo_mgcpc_ep_alloc(fi, MGW_EV_MGCP_TERM, mgw_fsm_priv->mgcpc, mgw_fsm_T_defs, fi->id, "%s", epname);
mgw_fsm_priv->mgcpc_ep_ci_hnb = osmo_mgcpc_ep_ci_add(mgw_fsm_priv->mgcpc_ep, "to-HNB");
osmo_mgcpc_ep_ci_request(mgw_fsm_priv->mgcpc_ep_ci_hnb, MGCP_VERB_CRCX, &mgw_info, fi, MGW_EV_MGCP_OK,
@ -496,13 +496,14 @@ static void mgw_fsm_failure_onenter(struct osmo_fsm_inst *fi, uint32_t prev_stat
static void mgw_fsm_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct mgw_fsm_priv *mgw_fsm_priv = fi->priv;
struct mgcp_client *mgcp_client;
switch (event) {
case MGW_EV_MGCP_TERM:
/* Put MGCP client back into MGW pool */
mgcp_client = osmo_mgcpc_ep_client(mgw_fsm_priv->mgcpc_ep);
mgcp_client_pool_put(mgcp_client);
if (mgw_fsm_priv->mgcpc) {
mgcp_client_pool_put(mgw_fsm_priv->mgcpc);
mgw_fsm_priv->mgcpc = NULL;
}
mgw_fsm_priv->mgcpc_ep = NULL;
LOGPFSML(fi, LOGL_ERROR, "Media gateway failed\n");
osmo_fsm_inst_state_chg(fi, MGW_ST_FAILURE, 0, 0);