aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2021-12-13 17:00:05 +0100
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2022-03-04 00:32:05 +0100
commite458501850adc80a5fcb6a99deac9b493fa0d799 (patch)
treece09c2aa89d3c807224e148196f952cbe129134b
parent20ae1be3f7171ae99393a89afc1ab399864ae659 (diff)
lchan/gscon: always clear both cross ref pointers
During specific release scenarios, it became clear that an lchan still pointed at a conn even after it had been deallocated. That was due to setting conn->lchan = NULL but not lchan->conn = NULL. Fix that. Do lchan_forget_conn() first, because during gscon_forget_lchan() we may enter the gscon clearing dance, which in case of no SCCP conn being present will soon / should immediately deallocate the conn. Related: OS#5337 Related: I8c8537acf6b47b121903197608636c43ae601a57 (osmo-bsc) Change-Id: Idbfe4672233ba8105eff5ba77ee07fd871358255
-rw-r--r--src/osmo-bsc/lchan_fsm.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index 5ae6df651..84f8dc5ef 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -478,8 +478,11 @@ static void lchan_reset(struct gsm_lchan *lchan)
{
LOG_LCHAN(lchan, LOGL_DEBUG, "Clearing lchan state\n");
- if (lchan->conn)
- gscon_forget_lchan(lchan->conn, lchan);
+ if (lchan->conn) {
+ struct gsm_subscriber_connection *conn = lchan->conn;
+ lchan_forget_conn(lchan);
+ gscon_forget_lchan(conn, lchan);
+ }
if (lchan->rqd_ref) {
talloc_free(lchan->rqd_ref);
@@ -1392,8 +1395,9 @@ static void lchan_fsm_wait_rf_release_ack_onenter(struct osmo_fsm_inst *fi, uint
* lchan_reset(), we make sure it does. But in case of releases from error handling, the
* conn might as well notice now already that its lchan is becoming unusable. */
if (lchan->conn) {
- gscon_forget_lchan(lchan->conn, lchan);
+ struct gsm_subscriber_connection *conn = lchan->conn;
lchan_forget_conn(lchan);
+ gscon_forget_lchan(conn, lchan);
}
rc = rsl_tx_rf_chan_release(lchan);