SPM: Improvements on connection handle creation and validation
This patch: - Removes the duplicated 'client_id' in conn_handle_t as there is a 'cliend_id' in psa_msg_t struct already. 'client_id' will be populated by tfm_spm_fill_msg(). - Removes the 'magic' member in conn_handle_t as its validation can be covered by 'is_valid_chunk_data_in_pool()'. - Simplifies the input args of handle creation and free API. - Creates an API to get spm working handle from the client handle, it is an equivalent API of 'spm_get_handle_by_msg_handle()', which is used for partition APIs to get the spm working handle from message handle, and validates the partition id. - Simplifies the check inside the handle validation API, moves the check of client id to the new API. Change-Id: Ia81d868071f7ffe5a79fae97e12a67c56056e5bb Signed-off-by: Kevin Peng <kevin.peng@arm.com> Co-authored-by: Mingyang Sun <mingyang.sun@arm.com>
This commit is contained in:
parent
15a37f8c9e
commit
e61e7050b6
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2021, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2018-2022, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
|
@ -73,7 +73,12 @@ typedef struct psa_msg_t {
|
|||
psa_handle_t handle; /* A reference generated by the SPM to the
|
||||
* message returned by psa_get().
|
||||
*/
|
||||
int32_t client_id; /* Partition ID of the sender of the message */
|
||||
int32_t client_id; /*
|
||||
* Partition ID of the sender of the
|
||||
* message:
|
||||
* - secure partition id;
|
||||
* - non secure client endpoint id.
|
||||
*/
|
||||
void *rhandle; /* Be useful for binding a connection to some
|
||||
* application-specific data or function
|
||||
* pointer within the RoT Service
|
||||
|
|
|
@ -147,13 +147,10 @@ struct conn_handle_t *tfm_spm_to_handle_instance(psa_handle_t user_handle)
|
|||
}
|
||||
|
||||
/* Service handle management functions */
|
||||
struct conn_handle_t *tfm_spm_create_conn_handle(struct service_t *service,
|
||||
int32_t client_id)
|
||||
struct conn_handle_t *tfm_spm_create_conn_handle(void)
|
||||
{
|
||||
struct conn_handle_t *p_handle;
|
||||
|
||||
TFM_CORE_ASSERT(service);
|
||||
|
||||
/* Get buffer for handle list structure from handle pool */
|
||||
p_handle = (struct conn_handle_t *)tfm_pool_alloc(conn_handle_pool);
|
||||
if (!p_handle) {
|
||||
|
@ -162,45 +159,31 @@ struct conn_handle_t *tfm_spm_create_conn_handle(struct service_t *service,
|
|||
|
||||
spm_memset(p_handle, 0, sizeof(*p_handle));
|
||||
|
||||
p_handle->service = service;
|
||||
p_handle->status = TFM_HANDLE_STATUS_IDLE;
|
||||
p_handle->client_id = client_id;
|
||||
|
||||
return p_handle;
|
||||
}
|
||||
|
||||
#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
|
||||
int32_t tfm_spm_validate_conn_handle(const struct conn_handle_t *conn_handle,
|
||||
int32_t client_id)
|
||||
int32_t tfm_spm_validate_conn_handle(const struct conn_handle_t *conn_handle)
|
||||
{
|
||||
/* Check the handle address is validated */
|
||||
/* Check the handle address is valid */
|
||||
if (is_valid_chunk_data_in_pool(conn_handle_pool,
|
||||
(uint8_t *)conn_handle) != true) {
|
||||
return SPM_ERROR_GENERIC;
|
||||
}
|
||||
|
||||
/* Check the handle caller is correct */
|
||||
if (conn_handle->client_id != client_id) {
|
||||
return SPM_ERROR_GENERIC;
|
||||
}
|
||||
|
||||
return SPM_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t tfm_spm_free_conn_handle(struct service_t *service,
|
||||
struct conn_handle_t *conn_handle)
|
||||
int32_t tfm_spm_free_conn_handle(struct conn_handle_t *conn_handle)
|
||||
{
|
||||
struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
|
||||
|
||||
TFM_CORE_ASSERT(service);
|
||||
TFM_CORE_ASSERT(conn_handle != NULL);
|
||||
|
||||
/* Clear magic as the handler is not used anymore */
|
||||
conn_handle->magic = 0;
|
||||
|
||||
CRITICAL_SECTION_ENTER(cs_assert);
|
||||
|
||||
/* Back handle buffer to pool */
|
||||
tfm_pool_free(conn_handle_pool, conn_handle);
|
||||
CRITICAL_SECTION_LEAVE(cs_assert);
|
||||
|
@ -342,7 +325,24 @@ int32_t tfm_spm_check_authorization(uint32_t sid,
|
|||
|
||||
/* Message functions */
|
||||
|
||||
struct conn_handle_t *spm_get_handle_by_user_handle(psa_handle_t msg_handle)
|
||||
struct conn_handle_t *spm_get_handle_by_client_handle(psa_handle_t handle,
|
||||
int32_t client_id)
|
||||
{
|
||||
struct conn_handle_t *p_conn_handle = tfm_spm_to_handle_instance(handle);
|
||||
|
||||
if (tfm_spm_validate_conn_handle(p_conn_handle) != SPM_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Validate the caller id in the connection handle equals client_id. */
|
||||
if (p_conn_handle->msg.client_id != client_id) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p_conn_handle;
|
||||
}
|
||||
|
||||
struct conn_handle_t *spm_get_handle_by_msg_handle(psa_handle_t msg_handle)
|
||||
{
|
||||
/*
|
||||
* The message handler passed by the caller is considered invalid in the
|
||||
|
@ -357,16 +357,7 @@ struct conn_handle_t *spm_get_handle_by_user_handle(psa_handle_t msg_handle)
|
|||
struct conn_handle_t *p_conn_handle =
|
||||
tfm_spm_to_handle_instance(msg_handle);
|
||||
|
||||
if (is_valid_chunk_data_in_pool(
|
||||
conn_handle_pool, (uint8_t *)p_conn_handle) != true) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the magic number is correct. This proves that the message
|
||||
* structure contains an active message.
|
||||
*/
|
||||
if (p_conn_handle->magic != TFM_MSG_MAGIC) {
|
||||
if (tfm_spm_validate_conn_handle(p_conn_handle) != SPM_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -401,7 +392,6 @@ void spm_fill_message(struct conn_handle_t *conn_handle,
|
|||
spm_memset(&conn_handle->msg, 0, sizeof(psa_msg_t));
|
||||
|
||||
THRD_SYNC_INIT(&conn_handle->ack_evnt);
|
||||
conn_handle->magic = TFM_MSG_MAGIC;
|
||||
conn_handle->service = service;
|
||||
conn_handle->p_client = GET_CURRENT_COMPONENT();
|
||||
conn_handle->caller_outvec = caller_outvec;
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
|
||||
#define SPM_INVALID_PARTITION_IDX (~0U)
|
||||
|
||||
#define TFM_MSG_MAGIC 0x15154343
|
||||
#define TFM_MSG_MAGIC_SFN 0x21216565
|
||||
|
||||
/* Get partition by thread or context data */
|
||||
|
@ -79,7 +78,7 @@
|
|||
|
||||
/* RoT connection handle list */
|
||||
struct conn_handle_t {
|
||||
void *rhandle; /* Reverse handle value */
|
||||
void *rhandle; /* Reverse handle value */
|
||||
uint32_t status; /*
|
||||
* Status of handle, three valid
|
||||
* options:
|
||||
|
@ -87,37 +86,30 @@ struct conn_handle_t {
|
|||
* TFM_HANDLE_STATUS_IDLE and
|
||||
* TFM_HANDLE_STATUS_CONNECT_ERROR
|
||||
*/
|
||||
int32_t client_id; /*
|
||||
* Partition ID of the sender of the
|
||||
* message:
|
||||
* - secure partition id;
|
||||
* - non secure client endpoint id.
|
||||
*/
|
||||
int32_t magic;
|
||||
struct partition_t *p_client; /* Caller partition */
|
||||
struct service_t *service; /* RoT service pointer */
|
||||
struct partition_t *p_client; /* Caller partition */
|
||||
struct service_t *service; /* RoT service pointer */
|
||||
union {
|
||||
struct sync_obj_t ack_evnt; /* IPC - Ack response event */
|
||||
uint32_t sfn_magic; /* SFN - Indicate a SFN message */
|
||||
struct sync_obj_t ack_evnt; /* IPC - Ack response event */
|
||||
uint32_t sfn_magic; /* SFN - Indicate a SFN message */
|
||||
};
|
||||
psa_msg_t msg; /* PSA message body */
|
||||
psa_invec invec[PSA_MAX_IOVEC]; /* Put in/out vectors in msg body */
|
||||
psa_msg_t msg; /* PSA message body */
|
||||
psa_invec invec[PSA_MAX_IOVEC]; /* Put in/out vectors in msg body */
|
||||
psa_outvec outvec[PSA_MAX_IOVEC];
|
||||
psa_outvec *caller_outvec; /*
|
||||
* Save caller outvec pointer for
|
||||
* write length update
|
||||
*/
|
||||
psa_outvec *caller_outvec; /*
|
||||
* Save caller outvec pointer for
|
||||
* write length update
|
||||
*/
|
||||
#ifdef TFM_MULTI_CORE_TOPOLOGY
|
||||
const void *caller_data; /*
|
||||
* Pointer to the private data of the
|
||||
* caller. It identifies the NSPE PSA
|
||||
* client calls in multi-core topology
|
||||
*/
|
||||
const void *caller_data; /*
|
||||
* Pointer to the private data of the
|
||||
* caller. It identifies the NSPE PSA
|
||||
* client calls in multi-core topology
|
||||
*/
|
||||
#endif
|
||||
#if PSA_FRAMEWORK_HAS_MM_IOVEC
|
||||
uint32_t iovec_status; /* MM-IOVEC status */
|
||||
uint32_t iovec_status; /* MM-IOVEC status */
|
||||
#endif
|
||||
struct conn_handle_t *p_handles; /* Handle(s) link */
|
||||
struct conn_handle_t *p_handles; /* Handle(s) link */
|
||||
};
|
||||
|
||||
/* Partition runtime type */
|
||||
|
@ -163,31 +155,24 @@ int32_t tfm_spm_partition_get_running_partition_id(void);
|
|||
/**
|
||||
* \brief Create connection handle for client connect
|
||||
*
|
||||
* \param[in] service Target service context pointer
|
||||
* \param[in] client_id Partition ID of the sender
|
||||
*
|
||||
* \retval NULL Create failed
|
||||
* \retval "Not NULL" Service handle created
|
||||
*/
|
||||
struct conn_handle_t *tfm_spm_create_conn_handle(struct service_t *service,
|
||||
int32_t client_id);
|
||||
struct conn_handle_t *tfm_spm_create_conn_handle(void);
|
||||
|
||||
/**
|
||||
* \brief Validate connection handle for client connect
|
||||
*
|
||||
* \param[in] conn_handle Handle to be validated
|
||||
* \param[in] client_id Partition ID of the sender
|
||||
*
|
||||
* \retval SPM_SUCCESS Success
|
||||
* \retval SPM_ERROR_GENERIC Invalid handle
|
||||
*/
|
||||
int32_t tfm_spm_validate_conn_handle(const struct conn_handle_t *conn_handle,
|
||||
int32_t client_id);
|
||||
int32_t tfm_spm_validate_conn_handle(const struct conn_handle_t *conn_handle);
|
||||
|
||||
/**
|
||||
* \brief Free connection handle which not used anymore.
|
||||
*
|
||||
* \param[in] service Target service context pointer
|
||||
* \param[in] conn_handle Connection handle created by
|
||||
* tfm_spm_create_conn_handle()
|
||||
*
|
||||
|
@ -195,8 +180,7 @@ int32_t tfm_spm_validate_conn_handle(const struct conn_handle_t *conn_handle,
|
|||
* \retval SPM_ERROR_BAD_PARAMETERS Bad parameters input
|
||||
* \retval "Does not return" Panic for not find service by handle
|
||||
*/
|
||||
int32_t tfm_spm_free_conn_handle(struct service_t *service,
|
||||
struct conn_handle_t *conn_handle);
|
||||
int32_t tfm_spm_free_conn_handle(struct conn_handle_t *conn_handle);
|
||||
|
||||
/******************** Partition management functions *************************/
|
||||
|
||||
|
@ -243,17 +227,31 @@ struct service_t *tfm_spm_get_service_by_sid(uint32_t sid);
|
|||
/************************ Message functions **********************************/
|
||||
|
||||
/**
|
||||
* \brief Get spm work handle by given user handle.
|
||||
* \brief Convert the given client handle to SPM recognised
|
||||
* handle and verify it.
|
||||
*
|
||||
* \param[in] msg_handle Message handle which is a reference generated
|
||||
* by the SPM to a specific message. A few
|
||||
* validations happen in this function before
|
||||
* the final result returns.
|
||||
* \param[in] handle A handle to an established connection that is
|
||||
* returned by a prior psa_connect call.
|
||||
*
|
||||
* \return The spm work handle.
|
||||
* \return A SPM recognised handle or NULL. It is NULL when
|
||||
* verification of the converted SPM handle fails.
|
||||
* \ref conn_handle_t structures
|
||||
*/
|
||||
struct conn_handle_t *spm_get_handle_by_user_handle(psa_handle_t msg_handle);
|
||||
struct conn_handle_t *spm_get_handle_by_client_handle(psa_handle_t handle,
|
||||
int32_t client_id);
|
||||
|
||||
/**
|
||||
* \brief Convert the given message handle to SPM recognised
|
||||
* handle and verify it.
|
||||
*
|
||||
* \param[in] msg_handle Message handle which is a reference generated
|
||||
* by the SPM to a specific message.
|
||||
*
|
||||
* \return A SPM recognised handle or NULL. It is NULL when
|
||||
* verification of the converted SPM handle fails.
|
||||
* \ref conn_handle_t structures
|
||||
*/
|
||||
struct conn_handle_t *spm_get_handle_by_msg_handle(psa_handle_t msg_handle);
|
||||
|
||||
/**
|
||||
* \brief Fill the user message in handle.
|
||||
|
|
|
@ -204,7 +204,7 @@ psa_status_t tfm_spm_client_psa_call(psa_handle_t handle,
|
|||
}
|
||||
|
||||
CRITICAL_SECTION_ENTER(cs_assert);
|
||||
conn_handle = tfm_spm_create_conn_handle(service, client_id);
|
||||
conn_handle = tfm_spm_create_conn_handle();
|
||||
CRITICAL_SECTION_LEAVE(cs_assert);
|
||||
|
||||
if (!conn_handle) {
|
||||
|
@ -215,11 +215,9 @@ psa_status_t tfm_spm_client_psa_call(psa_handle_t handle,
|
|||
handle = tfm_spm_to_user_handle(conn_handle);
|
||||
} else {
|
||||
#if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
|
||||
conn_handle = tfm_spm_to_handle_instance(handle);
|
||||
|
||||
/* It is a PROGRAMMER ERROR if an invalid handle was passed. */
|
||||
if (tfm_spm_validate_conn_handle(conn_handle, client_id)
|
||||
!= SPM_SUCCESS) {
|
||||
conn_handle = spm_get_handle_by_client_handle(handle, client_id);
|
||||
if (!conn_handle) {
|
||||
return PSA_ERROR_PROGRAMMER_ERROR;
|
||||
}
|
||||
|
||||
|
@ -372,7 +370,7 @@ psa_status_t tfm_spm_client_psa_connect(uint32_t sid, uint32_t version)
|
|||
* code to client when creation fails.
|
||||
*/
|
||||
CRITICAL_SECTION_ENTER(cs_assert);
|
||||
conn_handle = tfm_spm_create_conn_handle(service, client_id);
|
||||
conn_handle = tfm_spm_create_conn_handle();
|
||||
CRITICAL_SECTION_LEAVE(cs_assert);
|
||||
if (!conn_handle) {
|
||||
return PSA_ERROR_CONNECTION_BUSY;
|
||||
|
@ -405,12 +403,12 @@ psa_status_t tfm_spm_client_psa_close(psa_handle_t handle)
|
|||
|
||||
client_id = tfm_spm_get_client_id(ns_caller);
|
||||
|
||||
conn_handle = tfm_spm_to_handle_instance(handle);
|
||||
/*
|
||||
* It is a PROGRAMMER ERROR if an invalid handle was provided that is not
|
||||
* the null handle.
|
||||
*/
|
||||
if (tfm_spm_validate_conn_handle(conn_handle, client_id) != SPM_SUCCESS) {
|
||||
conn_handle = spm_get_handle_by_client_handle(handle, client_id);
|
||||
if (!conn_handle) {
|
||||
return PSA_ERROR_PROGRAMMER_ERROR;
|
||||
}
|
||||
|
||||
|
@ -546,7 +544,7 @@ size_t tfm_spm_partition_psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
|
|||
uint32_t priv_mode;
|
||||
|
||||
/* It is a fatal error if message handle is invalid */
|
||||
handle = spm_get_handle_by_user_handle(msg_handle);
|
||||
handle = spm_get_handle_by_msg_handle(msg_handle);
|
||||
if (!handle) {
|
||||
tfm_core_panic();
|
||||
}
|
||||
|
@ -615,7 +613,7 @@ size_t tfm_spm_partition_psa_skip(psa_handle_t msg_handle, uint32_t invec_idx,
|
|||
struct conn_handle_t *handle = NULL;
|
||||
|
||||
/* It is a fatal error if message handle is invalid */
|
||||
handle = spm_get_handle_by_user_handle(msg_handle);
|
||||
handle = spm_get_handle_by_msg_handle(msg_handle);
|
||||
if (!handle) {
|
||||
tfm_core_panic();
|
||||
}
|
||||
|
@ -676,7 +674,7 @@ void tfm_spm_partition_psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
|
|||
uint32_t priv_mode;
|
||||
|
||||
/* It is a fatal error if message handle is invalid */
|
||||
handle = spm_get_handle_by_user_handle(msg_handle);
|
||||
handle = spm_get_handle_by_msg_handle(msg_handle);
|
||||
if (!handle) {
|
||||
tfm_core_panic();
|
||||
}
|
||||
|
@ -746,7 +744,7 @@ psa_status_t tfm_spm_partition_psa_reply(psa_handle_t msg_handle,
|
|||
struct critical_section_t cs_assert = CRITICAL_SECTION_STATIC_INIT;
|
||||
|
||||
/* It is a fatal error if message handle is invalid */
|
||||
handle = spm_get_handle_by_user_handle(msg_handle);
|
||||
handle = spm_get_handle_by_msg_handle(msg_handle);
|
||||
if (!handle) {
|
||||
tfm_core_panic();
|
||||
}
|
||||
|
@ -772,7 +770,7 @@ psa_status_t tfm_spm_partition_psa_reply(psa_handle_t msg_handle,
|
|||
ret = msg_handle;
|
||||
} else if (status == PSA_ERROR_CONNECTION_REFUSED) {
|
||||
/* Refuse the client connection, indicating a permanent error. */
|
||||
tfm_spm_free_conn_handle(service, handle);
|
||||
tfm_spm_free_conn_handle(handle);
|
||||
ret = PSA_ERROR_CONNECTION_REFUSED;
|
||||
} else if (status == PSA_ERROR_CONNECTION_BUSY) {
|
||||
/* Fail the client connection, indicating a transient error. */
|
||||
|
@ -783,7 +781,7 @@ psa_status_t tfm_spm_partition_psa_reply(psa_handle_t msg_handle,
|
|||
break;
|
||||
case PSA_IPC_DISCONNECT:
|
||||
/* Service handle is not used anymore */
|
||||
tfm_spm_free_conn_handle(service, handle);
|
||||
tfm_spm_free_conn_handle(handle);
|
||||
|
||||
/*
|
||||
* If the message type is PSA_IPC_DISCONNECT, then the status code is
|
||||
|
@ -826,7 +824,7 @@ psa_status_t tfm_spm_partition_psa_reply(psa_handle_t msg_handle,
|
|||
*/
|
||||
update_caller_outvec_len(handle);
|
||||
if (SERVICE_IS_STATELESS(service->p_ldinf->flags)) {
|
||||
tfm_spm_free_conn_handle(service, handle);
|
||||
tfm_spm_free_conn_handle(handle);
|
||||
}
|
||||
} else {
|
||||
tfm_core_panic();
|
||||
|
@ -909,7 +907,7 @@ void tfm_spm_partition_psa_set_rhandle(psa_handle_t msg_handle, void *rhandle)
|
|||
struct conn_handle_t *handle;
|
||||
|
||||
/* It is a fatal error if message handle is invalid */
|
||||
handle = spm_get_handle_by_user_handle(msg_handle);
|
||||
handle = spm_get_handle_by_msg_handle(msg_handle);
|
||||
if (!handle) {
|
||||
tfm_core_panic();
|
||||
}
|
||||
|
@ -1035,7 +1033,7 @@ const void *tfm_spm_partition_psa_map_invec(psa_handle_t msg_handle,
|
|||
struct partition_t *partition = NULL;
|
||||
|
||||
/* It is a fatal error if message handle is invalid */
|
||||
handle = spm_get_handle_by_user_handle(msg_handle);
|
||||
handle = spm_get_handle_by_msg_handle(msg_handle);
|
||||
if (!handle) {
|
||||
tfm_core_panic();
|
||||
}
|
||||
|
@ -1110,7 +1108,7 @@ void tfm_spm_partition_psa_unmap_invec(psa_handle_t msg_handle,
|
|||
struct conn_handle_t *handle;
|
||||
|
||||
/* It is a fatal error if message handle is invalid */
|
||||
handle = spm_get_handle_by_user_handle(msg_handle);
|
||||
handle = spm_get_handle_by_msg_handle(msg_handle);
|
||||
if (!handle) {
|
||||
tfm_core_panic();
|
||||
}
|
||||
|
@ -1166,7 +1164,7 @@ void *tfm_spm_partition_psa_map_outvec(psa_handle_t msg_handle,
|
|||
struct partition_t *partition = NULL;
|
||||
|
||||
/* It is a fatal error if message handle is invalid */
|
||||
handle = spm_get_handle_by_user_handle(msg_handle);
|
||||
handle = spm_get_handle_by_msg_handle(msg_handle);
|
||||
if (!handle) {
|
||||
tfm_core_panic();
|
||||
}
|
||||
|
@ -1238,7 +1236,7 @@ void tfm_spm_partition_psa_unmap_outvec(psa_handle_t msg_handle,
|
|||
struct conn_handle_t *handle;
|
||||
|
||||
/* It is a fatal error if message handle is invalid */
|
||||
handle = spm_get_handle_by_user_handle(msg_handle);
|
||||
handle = spm_get_handle_by_msg_handle(msg_handle);
|
||||
if (!handle) {
|
||||
tfm_core_panic();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue