diff options
author | Harald Welte <laforge@gnumonks.org> | 2018-02-10 10:24:15 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2018-02-10 10:24:15 +0100 |
commit | 80620d2d7c7e3e32a9d9c498d1788eb3495b1bc9 (patch) | |
tree | fbf4e700d7fac7ae59a0f95e4140746621ba03e3 /src | |
parent | 69c54a8b3c4ec16b832474350ca4d1ef7ffb86d4 (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.c | 8 |
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); } } } |