Core: tfm_spm_get_msg_from_handle to check handle
Add extra checks to tfm_spm_get_msg_from_handle to validate message
handler:
- Check the handler is allocated from the pool
- Use magic to signal that a handler is active
Change-Id: Ic7b13cc1d61ae48e6112864bb2a1ce2059247e65
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
diff --git a/secure_fw/spm/spm_api_ipc.c b/secure_fw/spm/spm_api_ipc.c
index 70980f2..98f7a0e 100644
--- a/secure_fw/spm/spm_api_ipc.c
+++ b/secure_fw/spm/spm_api_ipc.c
@@ -90,6 +90,9 @@
tfm_panic();
}
+ /* Clear magic as the handler is not used anymore */
+ p_handle->internal_msg.magic = 0;
+
/* Remove node from handle list */
tfm_list_del_node(&p_handle->list);
@@ -241,34 +244,49 @@
struct tfm_msg_body_t *tfm_spm_get_msg_from_handle(psa_handle_t msg_handle)
{
/*
- * There may be one error handle passed by the caller in two conditions:
- * 1. Not a valid message handle.
- * 2. Handle between different Partitions. Partition A passes one handle
- * belong to other Partitions and tries to access other's data.
- * So, need do necessary checking to prevent those conditions.
+ * The message handler passed by the caller is considered invalid in the
+ * following cases:
+ * 1. Not a valid message handle. (The address of a message is not the
+ * address of a possible handle from the pool
+ * 2. Handle not belongs to the caller partition (The handle is either
+ * unused, or owned by anither partition)
+ * Check the conditions above
*/
+ struct tfm_conn_handle_t *connection_handle_address;
struct tfm_msg_body_t *msg;
uint32_t partition_id;
msg = (struct tfm_msg_body_t *)msg_handle;
- if (!msg) {
+
+ connection_handle_address =
+ TFM_GET_CONTAINER_PTR(msg, struct tfm_conn_handle_t, internal_msg);
+
+ if (is_valid_chunk_data_in_pool(
+ conn_handle_pool, (uint8_t *)connection_handle_address) != 1) {
return NULL;
}
/*
- * FixMe: For condition 1: using a magic number to define it's a message.
- * It needs to be an enhancement to check the handle belong to service.
+ * Check that the magic number is correct. This proves that the message
+ * structure contains an active message.
*/
if (msg->magic != TFM_MSG_MAGIC) {
return NULL;
}
- /* For condition 2: check if the partition ID is same */
+ /* Check that the running partition owns the message */
partition_id = tfm_spm_partition_get_running_partition_id();
if (partition_id != msg->service->partition->static_data->partition_id) {
return NULL;
}
+ /*
+ * FixMe: For condition 1 it should be checked whether the message belongs
+ * to the service. Skipping this check isn't a security risk as even if the
+ * message belongs to another service, the handle belongs to the calling
+ * partition.
+ */
+
return msg;
}