aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2018-02-10 10:24:15 +0100
committerHarald Welte <laforge@gnumonks.org>2018-02-10 10:24:15 +0100
commit80620d2d7c7e3e32a9d9c498d1788eb3495b1bc9 (patch)
treefbf4e700d7fac7ae59a0f95e4140746621ba03e3 /src
parent69c54a8b3c4ec16b832474350ca4d1ef7ffb86d4 (diff)
a_iface: Fix heap-use-after-free in a_clear_all()
We cannot use conn->a.conn_id after conn has been free'd inside msc_clear_request(). Let's store conn_id before that call to ensure we avoid an use-after-free situation. A more elegant (but more intrusive) solution would be to move the SCCP connection clearing into the FSM itself. Change-Id: Ibe41aa503e9f7cbeb05dce4b1a20b3eac85e619f Closes: OS#2922
Diffstat (limited to 'src')
-rw-r--r--src/libmsc/a_iface.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/libmsc/a_iface.c b/src/libmsc/a_iface.c
index b769b0aa4..3983ede61 100644
--- a/src/libmsc/a_iface.c
+++ b/src/libmsc/a_iface.c
@@ -605,14 +605,16 @@ void a_clear_all(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *bsc_ad
/* Clear only A connections and connections that actually
* belong to the specified BSC */
if (conn->via_ran == RAN_GERAN_A && memcmp(bsc_addr, &conn->a.bsc_addr, sizeof(conn->a.bsc_addr)) == 0) {
+ uint32_t conn_id = conn->a.conn_id;
LOGPCONN(conn, LOGL_NOTICE, "Dropping orphaned subscriber connection\n");
+ /* This call will/may talloc_free(conn), so we must save conn_id above */
msc_clear_request(conn, GSM48_CC_CAUSE_SWITCH_CONG);
/* If there is still an SCCP connection active, remove it now */
- if (check_connection_active(conn->a.conn_id)) {
- osmo_sccp_tx_disconn(scu, conn->a.conn_id, bsc_addr,
+ if (check_connection_active(conn_id)) {
+ osmo_sccp_tx_disconn(scu, conn_id, bsc_addr,
SCCP_RELEASE_CAUSE_END_USER_ORIGINATED);
- a_delete_bsc_con(conn->a.conn_id);
+ a_delete_bsc_con(conn_id);
}
}
}