Upstream optee-os has recently added a new
TA_AVB_CMD_READ_PERSIST_VALUE2 method, which fixes a problem with the
ABI of the old TA_AVB_CMD_READ_PERSIST_VALUE method: Callers could not
know whether the buffer they supplied was big enough, or whether the
output was silently truncated. With the new method,
TEE_ERROR_SHORT_BUFFER is returned, but with the output size parameter
updated to what would be the correct buffer size.
A new method was added instead of modifying the ABI of the existing
method, as there might be callers that work with a truncated return
value, but which would not be able to cope with an unexpected error
return.
Commit 8800cbe9b83 ("tee: sandbox: check for buffer size") partially
updated the sandbox version of optee-os to have the semantics that the
new method in upstream optee-os now has. It added logic to also return
the actual value size, but only in the success case -
params[1].u.memref.size was left untouched in the "return
TEE_ERROR_SHORT_BUFFER" case.
Align the sandbox implementation with optee-os: Silently return a
truncated value for the old method, but do return
TEE_ERROR_SHORT_BUFFER for the new method while also updating the
output size parameter.
Signed-off-by: Rasmus Villemoes <[email protected]>
---
drivers/tee/sandbox.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/tee/sandbox.c b/drivers/tee/sandbox.c
index 86b16a3bb8d..16e5d95616c 100644
--- a/drivers/tee/sandbox.c
+++ b/drivers/tee/sandbox.c
@@ -248,6 +248,7 @@ static u32 ta_avb_invoke_func(struct udevice *dev, u32
func, uint num_params,
return TEE_SUCCESS;
case TA_AVB_CMD_READ_PERSIST_VALUE:
+ case TA_AVB_CMD_READ_PERSIST_VALUE2:
res = check_params(TEE_PARAM_ATTR_TYPE_MEMREF_INPUT,
TEE_PARAM_ATTR_TYPE_MEMREF_INOUT,
TEE_PARAM_ATTR_TYPE_NONE,
@@ -268,8 +269,23 @@ static u32 ta_avb_invoke_func(struct udevice *dev, u32
func, uint num_params,
return TEE_ERROR_ITEM_NOT_FOUND;
tmp_sz = strlen(ep->data) + 1;
- if (value_sz < tmp_sz)
- return TEE_ERROR_SHORT_BUFFER;
+ if (value_sz < tmp_sz) {
+ /*
+ * For TA_AVB_CMD_READ_PERSIST_VALUE2, reject
+ * a too short output buffer, but do inform
+ * the caller of what would be the correct
+ * size.
+ */
+ if (func == TA_AVB_CMD_READ_PERSIST_VALUE2) {
+ params[1].u.memref.size = tmp_sz;
+ return TEE_ERROR_SHORT_BUFFER;
+ }
+ /*
+ * For TA_AVB_CMD_READ_PERSIST_VALUE, truncate
+ * the value to the given size.
+ */
+ tmp_sz = value_sz;
+ }
memcpy(value, ep->data, tmp_sz);
params[1].u.memref.size = tmp_sz;
--
2.55.0