mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-cbc.git
				synced 2025-11-04 06:03:35 +00:00 
			
		
		
		
	fix use-after-free in cbsp disconnect
Change-Id: I7d15606a83f13599300553b5d7b6532b2e5d90fe
This commit is contained in:
		@@ -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? */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user