Merge tag 'tee-memref-null-for-v5.10' of git://git.linaro.org/people/jens.wiklander/linux-tee into arm/drivers

Handle NULL pointer indication from tee client

Adds support to indicate NULL pointers instead of a valid buffer when
querying the needed size of a buffer.

* tag 'tee-memref-null-for-v5.10' of git://git.linaro.org/people/jens.wiklander/linux-tee:
  driver: tee: Handle NULL pointer indication from client

Link: https://lore.kernel.org/r/20200821102535.GA1872111@jade
Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
Olof Johansson
2020-08-21 09:20:29 -07:00
5 changed files with 56 additions and 17 deletions

View File

@@ -216,6 +216,8 @@ static void optee_get_version(struct tee_device *teedev,
if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
v.gen_caps |= TEE_GEN_CAP_REG_MEM;
if (optee->sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
v.gen_caps |= TEE_GEN_CAP_MEMREF_NULL;
*vers = v;
}
@@ -262,6 +264,11 @@ static int optee_open(struct tee_context *ctx)
mutex_init(&ctxdata->mutex);
INIT_LIST_HEAD(&ctxdata->sess_list);
if (optee->sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
ctx->cap_memref_null = true;
else
ctx->cap_memref_null = false;
ctx->data = ctxdata;
return 0;
}

View File

@@ -215,6 +215,9 @@ struct optee_smc_get_shm_config_result {
*/
#define OPTEE_SMC_SEC_CAP_DYNAMIC_SHM BIT(2)
/* Secure world supports Shared Memory with a NULL buffer reference */
#define OPTEE_SMC_SEC_CAP_MEMREF_NULL BIT(4)
#define OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES 9
#define OPTEE_SMC_EXCHANGE_CAPABILITIES \
OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_EXCHANGE_CAPABILITIES)

View File

@@ -383,25 +383,38 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params,
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
/*
* If we fail to get a pointer to a shared memory
* object (and increase the ref count) from an
* identifier we return an error. All pointers that
* has been added in params have an increased ref
* count. It's the callers responibility to do
* tee_shm_put() on all resolved pointers.
* If a NULL pointer is passed to a TA in the TEE,
* the ip.c IOCTL parameters is set to TEE_MEMREF_NULL
* indicating a NULL memory reference.
*/
shm = tee_shm_get_from_id(ctx, ip.c);
if (IS_ERR(shm))
return PTR_ERR(shm);
if (ip.c != TEE_MEMREF_NULL) {
/*
* If we fail to get a pointer to a shared
* memory object (and increase the ref count)
* from an identifier we return an error. All
* pointers that has been added in params have
* an increased ref count. It's the callers
* responibility to do tee_shm_put() on all
* resolved pointers.
*/
shm = tee_shm_get_from_id(ctx, ip.c);
if (IS_ERR(shm))
return PTR_ERR(shm);
/*
* Ensure offset + size does not overflow offset
* and does not overflow the size of the referred
* shared memory object.
*/
if ((ip.a + ip.b) < ip.a ||
(ip.a + ip.b) > shm->size) {
tee_shm_put(shm);
/*
* Ensure offset + size does not overflow
* offset and does not overflow the size of
* the referred shared memory object.
*/
if ((ip.a + ip.b) < ip.a ||
(ip.a + ip.b) > shm->size) {
tee_shm_put(shm);
return -EINVAL;
}
} else if (ctx->cap_memref_null) {
/* Pass NULL pointer to OP-TEE */
shm = NULL;
} else {
return -EINVAL;
}