fix use-after-free in cbsp disconnect

Change-Id: I7d15606a83f13599300553b5d7b6532b2e5d90fe
This commit is contained in:
Harald Welte
2020-12-31 14:25:24 +01:00
parent edf22db326
commit 3bffde541e
3 changed files with 35 additions and 3 deletions

View File

@@ -97,9 +97,10 @@ static int cbsp_cbc_closed_cb(struct osmo_stream_srv *conn)
{ {
struct osmo_cbsp_cbc_client *client = osmo_stream_srv_get_data(conn); struct osmo_cbsp_cbc_client *client = osmo_stream_srv_get_data(conn);
LOGPCC(client, LOGL_INFO, "connection closed\n"); LOGPCC(client, LOGL_INFO, "connection closed\n");
llist_del(&client->list);
osmo_fsm_inst_term(client->fi, OSMO_FSM_TERM_REQUEST, NULL); client->conn = NULL;
talloc_free(client); osmo_fsm_inst_dispatch(client->fi, CBSP_SRV_E_CMD_CLOSE, NULL);
return 0; return 0;
} }
@@ -173,6 +174,8 @@ void cbsp_cbc_client_tx(struct osmo_cbsp_cbc_client *client, struct osmo_cbsp_de
void cbsp_cbc_client_close(struct osmo_cbsp_cbc_client *client) void cbsp_cbc_client_close(struct osmo_cbsp_cbc_client *client)
{ {
if (client->fi)
osmo_fsm_inst_dispatch(client->fi, CBSP_SRV_E_CMD_CLOSE, NULL);
osmo_stream_srv_destroy(client->conn); osmo_stream_srv_destroy(client->conn);
/* FIXME: do we need to unlink/free the client? */ /* FIXME: do we need to unlink/free the client? */
} }

View File

@@ -53,6 +53,7 @@ static const struct value_string cbsp_server_event_names[] = {
{ CBSP_SRV_E_RX_KA_COMPL, "Rx Keep-Alive Complete" }, { CBSP_SRV_E_RX_KA_COMPL, "Rx Keep-Alive Complete" },
{ CBSP_SRV_E_RX_RESTART, "Rx Restart" }, { CBSP_SRV_E_RX_RESTART, "Rx Restart" },
{ CBSP_SRV_E_CMD_RESET, "RESET.cmd" }, { CBSP_SRV_E_CMD_RESET, "RESET.cmd" },
{ CBSP_SRV_E_CMD_CLOSE, "CLOSE.cmd" },
{ 0, NULL } { 0, NULL }
}; };
@@ -154,6 +155,30 @@ static int cbsp_server_fsm_timer_cb(struct osmo_fsm_inst *fi)
} }
} }
static void cbsp_server_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
case CBSP_SRV_E_CMD_CLOSE:
osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, NULL);
break;
}
}
static void cbsp_server_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
{
struct osmo_cbsp_cbc_client *client = (struct osmo_cbsp_cbc_client *) fi->priv;
if (client->conn)
osmo_stream_srv_destroy(client->conn);
llist_del(&client->list);
client->fi = NULL;
/* reparent the fsm_inst to the cbc as we're about to free() it's talloc
* parent 'client' */
talloc_steal(g_cbc, fi);
talloc_free(client);
}
static const struct osmo_fsm_state cbsp_server_fsm_states[] = { static const struct osmo_fsm_state cbsp_server_fsm_states[] = {
[CBSP_SRV_S_INIT] = { [CBSP_SRV_S_INIT] = {
.name = "INIT", .name = "INIT",
@@ -190,9 +215,12 @@ struct osmo_fsm cbsp_server_fsm = {
.name = "CBSP-SERVER", .name = "CBSP-SERVER",
.states = cbsp_server_fsm_states, .states = cbsp_server_fsm_states,
.num_states = ARRAY_SIZE(cbsp_server_fsm_states), .num_states = ARRAY_SIZE(cbsp_server_fsm_states),
.allstate_event_mask = S(CBSP_SRV_E_CMD_CLOSE),
.allstate_action = cbsp_server_fsm_allstate,
.timer_cb = cbsp_server_fsm_timer_cb, .timer_cb = cbsp_server_fsm_timer_cb,
.log_subsys = DCBSP, .log_subsys = DCBSP,
.event_names = cbsp_server_event_names, .event_names = cbsp_server_event_names,
.cleanup = cbsp_server_fsm_cleanup,
}; };
static int get_msg_id(const struct osmo_cbsp_decoded *dec) static int get_msg_id(const struct osmo_cbsp_decoded *dec)

View File

@@ -20,6 +20,7 @@ enum cbsp_server_event {
CBSP_SRV_E_RX_KA_COMPL, CBSP_SRV_E_RX_KA_COMPL,
CBSP_SRV_E_RX_RESTART, CBSP_SRV_E_RX_RESTART,
CBSP_SRV_E_CMD_RESET, CBSP_SRV_E_CMD_RESET,
CBSP_SRV_E_CMD_CLOSE,
}; };