From 7ec4c1f0ee2e4e04248cbb2d276094f8cb05ba6b Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Wed, 8 Jan 2020 21:10:04 +0100 Subject: sua.c: Avoid double free in sua_rx_msg()->...->mtp_user_prim_cb() Old commit of mine successfully fixed a memory leak, but apparently after some more investigation it seems to have introduced a double free of xua object in other code paths. Nowadays, it seems scrc_rx_mtp_xfer_ind_xua() is called from 3 different places: mtp_user_prim_cb() sua_rx_cl() sua_rx_co() Before present patch, first caller is not freeing the xua message and my old commit made scrc_rx_mtp_xfer_ind_xua() free it (by passing ownsership of the object). But the other 2 callers do free the xua object afterwards (actually the grandparent caller sua_rx_msg() does it), which means it would double-free the xua object. Let's move ownership out of scrc_rx_mtp_xfer_ind_xua() and let the caller free the xua object (only changes need on the first caller). This way everybody is happy and we keep the free() closer to the alloc(). Change-Id: Ia550b781b97adbdc0a0ad58a1075e5467e056f1e Related: OS#4348 Fixes: 9c3baa89fb6b3fc1ef588930f361d013f98a1e39 --- src/sccp_scrc.c | 16 ++++------------ src/sccp_user.c | 1 + 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/sccp_scrc.c b/src/sccp_scrc.c index db49299..e259d7c 100644 --- a/src/sccp_scrc.c +++ b/src/sccp_scrc.c @@ -438,14 +438,13 @@ int sccp_scrc_rx_sclc_msg(struct osmo_sccp_instance *inst, } /* Figure C.1/Q.714 Sheet 1 of 12, after we converted the - * MTP-TRANSFER.ind to SUA. Takes ownership of \a xua and frees it once processed. */ + * MTP-TRANSFER.ind to SUA. */ int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, struct xua_msg *xua) { struct osmo_sccp_addr called; uint32_t proto_class; struct xua_msg_part *hop_ctr_part; - int rc; LOGP(DLSS7, LOGL_DEBUG, "%s: %s\n", __func__, xua_msg_dump(xua, &xua_dialect_sua)); /* TODO: SCCP or nodal congestion? */ @@ -455,7 +454,6 @@ int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, /* Node 1 (Sheet 3) */ /* deliver to SCOC */ sccp_scoc_rx_from_scrc(inst, xua); - xua_msg_free(xua); return 0; } /* We only treat connectionless and CR below */ @@ -465,9 +463,7 @@ int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, /* Route on GT? */ if (called.ri != OSMO_SCCP_RI_GT) { /* Node 6 (Sheet 3) */ - rc = scrc_node_6(inst, xua, &called); - xua_msg_free(xua); - return rc; + return scrc_node_6(inst, xua, &called); } /* Message with hop-counter? */ hop_ctr_part = xua_msg_find_tag(xua, SUA_IEI_S7_HOP_CTR); @@ -476,9 +472,7 @@ int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, if (hop_counter <= 1) { /* Error: hop-counter violation */ /* node 4 */ - rc = scrc_node_4(inst, xua, SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); - xua_msg_free(xua); - return rc; + return scrc_node_4(inst, xua, SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION); } /* Decrement hop-counter */ hop_counter--; @@ -498,7 +492,5 @@ int scrc_rx_mtp_xfer_ind_xua(struct osmo_sccp_instance *inst, default: break; } - rc = scrc_translate_node_9(inst, xua, &called); - xua_msg_free(xua); - return rc; + return scrc_translate_node_9(inst, xua, &called); } diff --git a/src/sccp_user.c b/src/sccp_user.c index 929445f..49cc212 100644 --- a/src/sccp_user.c +++ b/src/sccp_user.c @@ -174,6 +174,7 @@ static int mtp_user_prim_cb(struct osmo_prim_hdr *oph, void *ctx) xua->mtp = omp->u.transfer; /* hand this primitive into SCCP via the SCRC code */ rc = scrc_rx_mtp_xfer_ind_xua(inst, xua); + xua_msg_free(xua); break; default: LOGP(DLSCCP, LOGL_ERROR, "Unknown primitive %u:%u receivd\n", -- cgit v1.2.3