bsc_api: Fix a use after free error in the Clear Request path

The implementation of bsc_hack would call subscr_con_free before
the BSC API has had the chance to call gsm0808_clear to try to
release other channels. Fix that by adding a return value.
diff --git a/openbsc/include/openbsc/bsc_api.h b/openbsc/include/openbsc/bsc_api.h
index b1fbb57..5cdc378 100644
--- a/openbsc/include/openbsc/bsc_api.h
+++ b/openbsc/include/openbsc/bsc_api.h
@@ -21,7 +21,7 @@
 			  uint16_t rr_cause);
 	void (*assign_fail)(struct gsm_subscriber_connection *conn,
 			 uint16_t rr_cause);
-	void (*clear_request)(struct gsm_subscriber_connection *conn,
+	int (*clear_request)(struct gsm_subscriber_connection *conn,
 			      uint32_t cause);
 	void (*clear_compl)(struct gsm_subscriber_connection *conn);
 };
diff --git a/openbsc/src/bsc/osmo_bsc_api.c b/openbsc/src/bsc/osmo_bsc_api.c
index eed58be..7b9f778 100644
--- a/openbsc/src/bsc/osmo_bsc_api.c
+++ b/openbsc/src/bsc/osmo_bsc_api.c
@@ -52,8 +52,9 @@
 {
 }
 
-static void bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
+static int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
 {
+	return 0;
 }
 
 static void bsc_clear_compl(struct gsm_subscriber_connection *conn)
diff --git a/openbsc/src/bsc_api.c b/openbsc/src/bsc_api.c
index 21d0ae7..e8f42d2 100644
--- a/openbsc/src/bsc_api.c
+++ b/openbsc/src/bsc_api.c
@@ -241,6 +241,7 @@
 	struct bsc_api *bsc;
 	struct gsm_lchan *lchan;
 	struct gsm_subscriber_connection *conn;
+	int destruct = 1;
 
 	if (subsys != SS_LCHAN || signal != S_LCHAN_UNEXPECTED_RELEASE)
 		return 0;
@@ -255,7 +256,7 @@
 
 	conn = lchan->conn;
 	if (bsc->clear_request)
-		bsc->clear_request(conn, 0);
+		destruct = bsc->clear_request(conn, 0);
 
 	/* now give up all channels */
 	if (conn->lchan == lchan)
@@ -264,6 +265,9 @@
 		conn->ho_lchan = NULL;
 	gsm0808_clear(conn);
 
+	if (destruct)
+		subscr_con_free(conn);
+
 	return 0;
 }
 
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index ddda19b..0bd6de2 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -328,8 +328,6 @@
 		if (trans->conn == conn)
 			trans_free(trans);
 	}
-
-	subscr_con_free(conn);
 }
 
 /* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */
diff --git a/openbsc/src/osmo_msc.c b/openbsc/src/osmo_msc.c
index 1fad510..0ed973b 100644
--- a/openbsc/src/osmo_msc.c
+++ b/openbsc/src/osmo_msc.c
@@ -36,9 +36,10 @@
 		gsm411_sapi_n_reject(conn);
 }
 
-static void msc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
+static int msc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
 {
 	gsm0408_clear_request(conn, cause);
+	return 1;
 }
 
 static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,