From 05c68841a835b3bbc5a95fa809e136e4e376154c Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Wed, 3 Nov 2010 19:01:58 +0100 Subject: [PATCH] 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. --- openbsc/include/openbsc/bsc_api.h | 2 +- openbsc/src/bsc/osmo_bsc_api.c | 3 ++- openbsc/src/bsc_api.c | 6 +++++- openbsc/src/gsm_04_08.c | 2 -- openbsc/src/osmo_msc.c | 3 ++- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/openbsc/include/openbsc/bsc_api.h b/openbsc/include/openbsc/bsc_api.h index b1fbb5711..5cdc37844 100644 --- a/openbsc/include/openbsc/bsc_api.h +++ b/openbsc/include/openbsc/bsc_api.h @@ -21,7 +21,7 @@ struct bsc_api { 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 eed58be06..7b9f77844 100644 --- a/openbsc/src/bsc/osmo_bsc_api.c +++ b/openbsc/src/bsc/osmo_bsc_api.c @@ -52,8 +52,9 @@ static void bsc_assign_fail(struct gsm_subscriber_connection *conn, uint32_t cau { } -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 21d0ae7a3..e8f42d275 100644 --- a/openbsc/src/bsc_api.c +++ b/openbsc/src/bsc_api.c @@ -241,6 +241,7 @@ static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal, 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 @@ static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal, 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 @@ static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal, 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 ddda19b75..0bd6de225 100644 --- a/openbsc/src/gsm_04_08.c +++ b/openbsc/src/gsm_04_08.c @@ -328,8 +328,6 @@ void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t caus 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 1fad510fe..0ed973b10 100644 --- a/openbsc/src/osmo_msc.c +++ b/openbsc/src/osmo_msc.c @@ -36,9 +36,10 @@ static void msc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci) 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,