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.
This commit is contained in:
parent
85334f1309
commit
05c68841a8
|
@ -21,7 +21,7 @@ struct bsc_api {
|
||||||
uint16_t rr_cause);
|
uint16_t rr_cause);
|
||||||
void (*assign_fail)(struct gsm_subscriber_connection *conn,
|
void (*assign_fail)(struct gsm_subscriber_connection *conn,
|
||||||
uint16_t rr_cause);
|
uint16_t rr_cause);
|
||||||
void (*clear_request)(struct gsm_subscriber_connection *conn,
|
int (*clear_request)(struct gsm_subscriber_connection *conn,
|
||||||
uint32_t cause);
|
uint32_t cause);
|
||||||
void (*clear_compl)(struct gsm_subscriber_connection *conn);
|
void (*clear_compl)(struct gsm_subscriber_connection *conn);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
static void bsc_clear_compl(struct gsm_subscriber_connection *conn)
|
||||||
|
|
|
@ -241,6 +241,7 @@ static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal,
|
||||||
struct bsc_api *bsc;
|
struct bsc_api *bsc;
|
||||||
struct gsm_lchan *lchan;
|
struct gsm_lchan *lchan;
|
||||||
struct gsm_subscriber_connection *conn;
|
struct gsm_subscriber_connection *conn;
|
||||||
|
int destruct = 1;
|
||||||
|
|
||||||
if (subsys != SS_LCHAN || signal != S_LCHAN_UNEXPECTED_RELEASE)
|
if (subsys != SS_LCHAN || signal != S_LCHAN_UNEXPECTED_RELEASE)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -255,7 +256,7 @@ static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal,
|
||||||
|
|
||||||
conn = lchan->conn;
|
conn = lchan->conn;
|
||||||
if (bsc->clear_request)
|
if (bsc->clear_request)
|
||||||
bsc->clear_request(conn, 0);
|
destruct = bsc->clear_request(conn, 0);
|
||||||
|
|
||||||
/* now give up all channels */
|
/* now give up all channels */
|
||||||
if (conn->lchan == lchan)
|
if (conn->lchan == lchan)
|
||||||
|
@ -264,6 +265,9 @@ static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal,
|
||||||
conn->ho_lchan = NULL;
|
conn->ho_lchan = NULL;
|
||||||
gsm0808_clear(conn);
|
gsm0808_clear(conn);
|
||||||
|
|
||||||
|
if (destruct)
|
||||||
|
subscr_con_free(conn);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -328,8 +328,6 @@ void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t caus
|
||||||
if (trans->conn == conn)
|
if (trans->conn == conn)
|
||||||
trans_free(trans);
|
trans_free(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
subscr_con_free(conn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */
|
/* Chapter 9.2.14 : Send LOCATION UPDATING REJECT */
|
||||||
|
|
|
@ -36,9 +36,10 @@ static void msc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci)
|
||||||
gsm411_sapi_n_reject(conn);
|
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);
|
gsm0408_clear_request(conn, cause);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
|
static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
|
||||||
|
|
Loading…
Reference in New Issue