When calling TEE_InvokeTACommand() with a non-NULL memref of size
zero, function tee_svc_copy_param() will return
TEE_ERROR_BAD_PARAMETERS resulting in a panic later on.
In regard to the TEE_PARAM_TYPE_MEMREF_{INPUT,OUTPUT,INOUT} types, the
Global Platform specification says [1]:
params[i].memref.size SHALL be initialized with a memory buffer that
is accessible with the access rights described in the type. The
buffer can be NULL, in which case size SHALL be set to 0 .
Note that the specification only specifies that NULL implies a size of
zero. The reciprocal: "a size of zero implies NULL" is undefined.
It is even more confusing considering that non-NULL buffer with a size
of zero are explicitly allowed by the client API [2]:
This design allows a non-NULL buffer with a size of 0 bytes to allow
trivial integration with any implementations of the C library
malloc, in which is valid to allocate a zero byte buffer and receive
a non-NULL pointer which may not be de-referenced in return.
This could become a pitfall if a TA forwards a memref received from
the REE to another TA.
Allow the TAs to pass non-NULL memref of size zero to other TAs
through TEE_InvokeTACommand() by changing the non-NULL pointer into a
NULL one in such a case.
[1] TEE Internal Core API Specification – Public Release v1.3.1,
§4.9.4 "Operation Parameters in the Internal Client API"
Table 4-15: "Interpretation of params[i] on Entry to Internal Client API"
[2] TEE Client API Specification v1.0,
§4.5.4 TEEC_RegisterSharedMemory,
paragraph "Implementers' Notes"
Signed-off-by: Vincent Mailhol <mailhol.vincent(a)wanadoo.fr>
---
core/tee/tee_svc.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/core/tee/tee_svc.c b/core/tee/tee_svc.c
index f4158dca1..237a27de9 100644
--- a/core/tee/tee_svc.c
+++ b/core/tee/tee_svc.c
@@ -700,11 +700,13 @@ static TEE_Result tee_svc_copy_param(struct ts_session *sess,
case TEE_PARAM_TYPE_MEMREF_INOUT:
va = (void *)param->u[n].mem.offs;
s = param->u[n].mem.size;
- if (!va) {
- if (s)
- return TEE_ERROR_BAD_PARAMETERS;
+ if (!s) {
+ param->u[n].mem.mobj = NULL;
break;
}
+ if (!va)
+ return TEE_ERROR_BAD_PARAMETERS;
+
/* uTA cannot expose its private memory */
if (vm_buf_is_inside_um_private(&utc->uctx, va, s))
return TEE_ERROR_BAD_PARAMETERS;
--
2.25.1
This series introduces TEE system sessions for TEE service sessions that
require TEE to provision resources to prevent deadlock when clients call
the TEE.
This deadlock situation can happen when a TEE service is used by low
level system resources as for example when Linux kernel uses SCMI
service embedded in TEE for clock, reset, regulator, etc... controls.
This case is detailled in patch 2/4:
> This feature is needed to prevent a system deadlock when several TEE
> client applications invoke TEE, consuming all TEE thread contexts
> available in the secure world. The deadlock can happen in the OP-TEE
> driver for example if all these TEE threads issue an RPC call from TEE
> to Linux OS to access an eMMC RPMB partition (TEE secure storage) which
> device clock or regulator controller is accessed through an OP-TEE SCMI
> services. In that case, Linux SCMI driver must reach OP-TEE SCMI
> service without waiting until one of the consumed TEE threads is freed.
Etienne Carriere (4):
tee: optee: system call property
tee: system session
tee: optee: support tracking system threads
firmware: arm_scmi: optee: use optee system invocation
drivers/firmware/arm_scmi/optee.c | 4 +
drivers/tee/optee/call.c | 130 ++++++++++++++++++++++++++++--
drivers/tee/optee/core.c | 5 +-
drivers/tee/optee/ffa_abi.c | 13 +--
drivers/tee/optee/optee_private.h | 29 ++++++-
drivers/tee/optee/smc_abi.c | 31 ++++---
drivers/tee/tee_core.c | 8 ++
include/linux/tee_drv.h | 16 ++++
8 files changed, 209 insertions(+), 27 deletions(-)
---
Changes since v11:
- Changes patch 3/4, other are unchanged.
--
2.25.1
This series introduces the tee based EFI Runtime Variable Service.
The eMMC device is typically owned by the non-secure world(linux in
this case). There is an existing solution utilizing eMMC RPMB partition
for EFI Variables, it is implemented by interacting with
OP-TEE, StandaloneMM(as EFI Variable Service Pseudo TA), eMMC driver
and tee-supplicant. The last piece is the tee-based variable access
driver to interact with OP-TEE and StandaloneMM.
Changelog:
v7 -> v8
Only patch #3 "efi: Add tee-based EFI variable driver" is updated.
- fix typos
- refactor error handling, direct return if applicable
- use devm_add_action_or_reset() for closing of tee context/session
- remove obvious comment
v6 -> v7
Patch #1-#4 are not updated.
Patch #5 is added into this series, original patch is here:
https://lore.kernel.org/all/20230609094532.562934-1-ilias.apalodimas@linaro…
There are two issues in the v6 series and v7 series addresses those.
1) efivar ops is not restored when the tee-supplicant daemon terminates.
-> As the following patch says, user must remove the device before
terminating tee-supplicant daemon.
https://lore.kernel.org/all/20230728134832.326467-1-sumit.garg@linaro.org/
2) cause panic when someone remounts the efivarfs as RW even if
SetVariable is not supported
-> The fifth patch addresses this issue.
"[PATCH v7 5/5] efivarfs: force RO when remounting if SetVariable is
not supported"
v5 -> v6
- new patch #4 is added in this series, #1-#3 patches are unchanged.
automatically update super block flag when the efivarops support
SetVariable runtime service, so that user does not need to manually
remount the efivarfs as RW.
v4 -> v5
- rebase to efi-next based on v6.4-rc1
- set generic_ops.query_variable_info, it works as expected as follows.
$ df -h /sys/firmware/efi/efivars/
Filesystem Size Used Avail Use% Mounted on
efivarfs 16K 1.3K 15K 8% /sys/firmware/efi/efivars
v3 -> v4:
- replace the reference from EDK2 to PI Specification
- remove EDK2 source code reference comments
- prepare nonblocking variant of set_variable, it just returns
EFI_UNSUPPORTED
- remove redundant buffer size check
- argument name change in mm_communicate
- function interface changes in setup_mm_hdr to remove (void **) cast
v2 -> v3:
- add CONFIG_EFI dependency to TEE_STMM_EFI
- add missing return code check for tee_client_invoke_func()
- directly call efivars_register/unregister from tee_stmm_efi.c
rfc v1 -> v2:
- split patch into three patches, one for drivers/tee,
one for include/linux/efi.h, and one for the driver/firmware/efi/stmm
- context/session management into probe() and remove() same as other tee
client driver
- StMM variable driver is moved from driver/tee/optee to driver/firmware/efi
- use "tee" prefix instead of "optee" in driver/firmware/efi/stmm/tee_stmm_efi.c,
this file does not contain op-tee specific code, abstracted by tee layer and
StMM variable driver will work on other tee implementation.
- PTA_STMM_CMD_COMMUNICATE -> PTA_STMM_CMD_COMMUNICATE
- implement query_variable_store() but currently not used
- no use of TEEC_SUCCESS, it is defined in driver/tee/optee/optee_private.h.
Other tee client drivers use 0 instead of using TEEC_SUCCESS
- remove TEEC_ERROR_EXCESS_DATA status, it is referred just to output
error message
Ilias Apalodimas (1):
efivarfs: force RO when remounting if SetVariable is not supported
Masahisa Kojima (4):
efi: expose efivar generic ops register function
efi: Add EFI_ACCESS_DENIED status code
efi: Add tee-based EFI variable driver
efivarfs: automatically update super block flag
drivers/firmware/efi/Kconfig | 15 +
drivers/firmware/efi/Makefile | 1 +
drivers/firmware/efi/efi.c | 18 +
drivers/firmware/efi/stmm/mm_communication.h | 236 +++++++
drivers/firmware/efi/stmm/tee_stmm_efi.c | 612 +++++++++++++++++++
drivers/firmware/efi/vars.c | 8 +
fs/efivarfs/super.c | 45 ++
include/linux/efi.h | 12 +
8 files changed, 947 insertions(+)
create mode 100644 drivers/firmware/efi/stmm/mm_communication.h
create mode 100644 drivers/firmware/efi/stmm/tee_stmm_efi.c
base-commit: f6e6e95ce16205025b7b8680a66c30a0c4ec2270
--
2.30.2
Currently supplicant dependent optee device enumeration only registers
devices whenever tee-supplicant is invoked for the first time. But it
forgets to remove devices when tee-supplicant daemon stops running and
closes its context gracefully. This leads to following error for fTPM
driver during reboot/shutdown:
[ 73.466791] tpm tpm0: ftpm_tee_tpm_op_send: SUBMIT_COMMAND invoke error: 0xffff3024
Fix this by separating supplicant dependent devices so that the
user-space service can detach supplicant devices before closing the
supplicant. While at it use the global system workqueue for OP-TEE bus
scanning work rather than our own custom one.
Reported-by: Jan Kiszka <jan.kiszka(a)siemens.com>
Link: https://github.com/OP-TEE/optee_os/issues/6094
Fixes: 5f178bb71e3a ("optee: enable support for multi-stage bus enumeration")
Signed-off-by: Sumit Garg <sumit.garg(a)linaro.org>
---
Changes in v2:
Apologies for taking it too long push this v2. Actually I did brainstorm
how to best fix this tee-supplicant dependent device probing. Its hard
to predict the lifetime of user-space daemon from kernel space. So
following is the least intrusive approach:
- Use device names to seperate out tee-supplicant dependent devices via
this patch.
- Since user-space service is aware about tee-supplicant lifespan, so
allow the user-space service to unbind tee-supplicant dependent
devices before killing the supplicant. Following command has to be
added to the tee-supplicant service file.
$ for dev in /sys/bus/tee/devices/*; do if [[ "$dev" == *"optee-ta-supp-"* ]]; \
then echo $(basename "$dev") > $dev/driver/unbind; fi done
drivers/tee/optee/core.c | 13 ++-----------
drivers/tee/optee/device.c | 13 ++++++++++---
drivers/tee/optee/optee_private.h | 2 --
3 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index d01ca47f7bde..8ee3c71bd989 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -15,7 +15,6 @@
#include <linux/string.h>
#include <linux/tee_drv.h>
#include <linux/types.h>
-#include <linux/workqueue.h>
#include "optee_private.h"
int optee_pool_op_alloc_helper(struct tee_shm_pool *pool, struct tee_shm *shm,
@@ -110,12 +109,7 @@ int optee_open(struct tee_context *ctx, bool cap_memref_null)
if (!optee->scan_bus_done) {
INIT_WORK(&optee->scan_bus_work, optee_bus_scan);
- optee->scan_bus_wq = create_workqueue("optee_bus_scan");
- if (!optee->scan_bus_wq) {
- kfree(ctxdata);
- return -ECHILD;
- }
- queue_work(optee->scan_bus_wq, &optee->scan_bus_work);
+ schedule_work(&optee->scan_bus_work);
optee->scan_bus_done = true;
}
}
@@ -159,10 +153,7 @@ void optee_release_supp(struct tee_context *ctx)
struct optee *optee = tee_get_drvdata(ctx->teedev);
optee_release_helper(ctx, optee_close_session_helper);
- if (optee->scan_bus_wq) {
- destroy_workqueue(optee->scan_bus_wq);
- optee->scan_bus_wq = NULL;
- }
+
optee_supp_release(&optee->supp);
}
diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c
index 64f0e047c23d..78fc0a15c463 100644
--- a/drivers/tee/optee/device.c
+++ b/drivers/tee/optee/device.c
@@ -60,9 +60,10 @@ static void optee_release_device(struct device *dev)
kfree(optee_device);
}
-static int optee_register_device(const uuid_t *device_uuid)
+static int optee_register_device(const uuid_t *device_uuid, u32 func)
{
struct tee_client_device *optee_device = NULL;
+ const char *dev_name_fmt = NULL;
int rc;
optee_device = kzalloc(sizeof(*optee_device), GFP_KERNEL);
@@ -71,7 +72,13 @@ static int optee_register_device(const uuid_t *device_uuid)
optee_device->dev.bus = &tee_bus_type;
optee_device->dev.release = optee_release_device;
- if (dev_set_name(&optee_device->dev, "optee-ta-%pUb", device_uuid)) {
+
+ if (func == PTA_CMD_GET_DEVICES_SUPP)
+ dev_name_fmt = "optee-ta-supp-%pUb";
+ else
+ dev_name_fmt = "optee-ta-%pUb";
+
+ if (dev_set_name(&optee_device->dev, dev_name_fmt, device_uuid)) {
kfree(optee_device);
return -ENOMEM;
}
@@ -142,7 +149,7 @@ static int __optee_enumerate_devices(u32 func)
num_devices = shm_size / sizeof(uuid_t);
for (idx = 0; idx < num_devices; idx++) {
- rc = optee_register_device(&device_uuid[idx]);
+ rc = optee_register_device(&device_uuid[idx], func);
if (rc)
goto out_shm;
}
diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h
index 6dcecb83c893..af4aa266c3fb 100644
--- a/drivers/tee/optee/optee_private.h
+++ b/drivers/tee/optee/optee_private.h
@@ -193,7 +193,6 @@ struct optee_ops {
* @pool: shared memory pool
* @rpc_param_count: If > 0 number of RPC parameters to make room for
* @scan_bus_done flag if device registation was already done.
- * @scan_bus_wq workqueue to scan optee bus and register optee drivers
* @scan_bus_work workq to scan optee bus and register optee drivers
*/
struct optee {
@@ -212,7 +211,6 @@ struct optee {
struct tee_shm_pool *pool;
unsigned int rpc_param_count;
bool scan_bus_done;
- struct workqueue_struct *scan_bus_wq;
struct work_struct scan_bus_work;
};
--
2.34.1
[BCC all OP-TEE maintainers]
Hi OP-TEE maintainers & contributors,
OP-TEE v4.0.0 is scheduled to be released on 2023-10-20. So, now is
a good time to start testing the master branch on the various platforms
and report/fix any bugs.
The GitHub pull request for collecting Tested-by tags or any other
comments is https://github.com/OP-TEE/optee_os/pull/6341.
As usual, we will create a release candidate tag one week before the
release date for final testing.
Note that this is a major version update. We will be merging some pull
requests that may break backward compatibility in some (limited) way
just before creating the 4.0.0-rc1 tag. These pull requests have "[v4]" in
their title and can be found here:
https://github.com/OP-TEE/optee_os/pulls?q=is%3Apr+is%3Aopen+in%3Atitle+%5B…
In addition to that you can find some additional information related to
releases here: https://optee.readthedocs.io/en/latest/general/releases.html
Regards,
--
Jerome Forissier
This series introduces TEE system sessions for TEE service sessions that
require TEE to provision resources to prevent deadlock when clients call
the TEE.
This deadlock situation can happen when a TEE service is used by low
level system resources as for example when Linux kernel uses SCMI
service embedded in TEE for clock, reset, regulator, etc... controls.
This case is detailled in patch 2/4:
> This feature is needed to prevent a system deadlock when several TEE
> client applications invoke TEE, consuming all TEE thread contexts
> available in the secure world. The deadlock can happen in the OP-TEE
> driver for example if all these TEE threads issue an RPC call from TEE
> to Linux OS to access an eMMC RPMB partition (TEE secure storage) which
> device clock or regulator controller is accessed through an OP-TEE SCMI
> services. In that case, Linux SCMI driver must reach OP-TEE SCMI
> service without waiting until one of the consumed TEE threads is freed.
Etienne Carriere (4):
tee: optee: system call property
tee: system session
tee: optee: support tracking system threads
firmware: arm_scmi: optee: use optee system invocation
drivers/firmware/arm_scmi/optee.c | 4 +
drivers/tee/optee/call.c | 152 +++++++++++++++++++++++++++---
drivers/tee/optee/core.c | 5 +-
drivers/tee/optee/ffa_abi.c | 13 +--
drivers/tee/optee/optee_private.h | 33 ++++++-
drivers/tee/optee/smc_abi.c | 31 ++++--
drivers/tee/tee_core.c | 8 ++
include/linux/tee_drv.h | 16 ++++
8 files changed, 227 insertions(+), 35 deletions(-)
--
2.25.1