fix(ff-a): prevent mem-share/lend from SP to NS-endpoint
Only FFA_MEM_DONATE_32 is permitted from SP to NS-endpoint.
Signed-off-by: Maksims Svecovs <maksims.svecovs@arm.com>
Change-Id: I3fe611b5c239e896af421ed430770d6c25af2096
diff --git a/src/api.c b/src/api.c
index a507e34..ac3a741 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2432,6 +2432,11 @@
goto out;
}
+ if (!plat_ffa_is_memory_send_valid(to->id, share_func)) {
+ ret = ffa_error(FFA_DENIED);
+ goto out;
+ }
+
if (to->id == HF_TEE_VM_ID) {
/*
* The 'to' VM lock is only needed in the case that it is the
diff --git a/src/arch/aarch64/plat/ffa/absent.c b/src/arch/aarch64/plat/ffa/absent.c
index c6a7d4c..17eec1b 100644
--- a/src/arch/aarch64/plat/ffa/absent.c
+++ b/src/arch/aarch64/plat/ffa/absent.c
@@ -42,6 +42,18 @@
}
/**
+ * Check validity of the FF-A memory send function attempt.
+ */
+bool plat_ffa_is_memory_send_valid(ffa_vm_id_t receiver_vm_id,
+ uint32_t share_func)
+{
+ (void)receiver_vm_id;
+ (void)share_func;
+
+ return false;
+}
+
+/**
* Check validity of a FF-A direct message request.
*/
bool plat_ffa_is_direct_request_valid(struct vcpu *current,
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index b7361fb..a53375b 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -140,6 +140,23 @@
}
/**
+ * Check validity of the FF-A memory send function attempt.
+ */
+bool plat_ffa_is_memory_send_valid(ffa_vm_id_t receiver_vm_id,
+ uint32_t share_func)
+{
+ /*
+ * Currently memory interfaces are not forwarded from hypervisor to
+ * SPMC. However, in absence of SPMC this function should allow
+ * NS-endpoint to SP memory send in order for trusty tests to work.
+ */
+
+ (void)share_func;
+ (void)receiver_vm_id;
+ return true;
+}
+
+/**
* Check validity of a FF-A direct message request.
*/
bool plat_ffa_is_direct_request_valid(struct vcpu *current,
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index b24ed8a..203b71e 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -168,6 +168,42 @@
}
/**
+ * Check validity of the FF-A memory send function attempt.
+ */
+bool plat_ffa_is_memory_send_valid(ffa_vm_id_t receiver_vm_id,
+ uint32_t share_func)
+{
+ bool result = false;
+
+ /*
+ * Currently SP to NS-endpoint memory donation is limited:
+ * In it's current implementation SPMC is not aware of the memory type
+ * being donated and can not ensure that the memory type is marked as
+ * non-secure when SP is donating to NS-endpoint.
+ */
+ switch (share_func) {
+ case FFA_MEM_DONATE_32:
+ result = true;
+ break;
+ case FFA_MEM_LEND_32:
+ case FFA_MEM_SHARE_32:
+ /* SP to VM not allowed, VM to VM should not end up here */
+ result = vm_id_is_current_world(receiver_vm_id);
+ if (!result) {
+ dlog_verbose(
+ "SP to NS-endpoint memory sharing/lending is "
+ "not "
+ "permitted.\n");
+ }
+ break;
+ default:
+ result = false;
+ }
+
+ return result;
+}
+
+/**
* Check validity of a FF-A direct message request.
*/
bool plat_ffa_is_direct_request_valid(struct vcpu *current,
diff --git a/src/arch/fake/hypervisor/ffa.c b/src/arch/fake/hypervisor/ffa.c
index 91bebd4..236fb16 100644
--- a/src/arch/fake/hypervisor/ffa.c
+++ b/src/arch/fake/hypervisor/ffa.c
@@ -29,6 +29,15 @@
{
}
+bool plat_ffa_is_memory_send_valid(ffa_vm_id_t receiver_vm_id,
+ uint32_t share_func)
+{
+ (void)receiver_vm_id;
+ (void)share_func;
+
+ return true;
+}
+
bool plat_ffa_is_direct_request_valid(struct vcpu *current,
ffa_vm_id_t sender_vm_id,
ffa_vm_id_t receiver_vm_id)