in tee_core.c [732:776]
static int params_from_supp(struct tee_param *params, size_t num_params,
struct tee_ioctl_param __user *uparams)
{
size_t n;
for (n = 0; n < num_params; n++) {
struct tee_param *p = params + n;
struct tee_ioctl_param ip;
if (copy_from_user(&ip, uparams + n, sizeof(ip)))
return -EFAULT;
/* All unused attribute bits has to be zero */
if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_MASK)
return -EINVAL;
p->attr = ip.attr;
switch (ip.attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
/* Only out and in/out values can be updated */
p->u.value.a = ip.a;
p->u.value.b = ip.b;
p->u.value.c = ip.c;
break;
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
/*
* Only the size of the memref can be updated.
* Since we don't have access to the original
* parameters here, only store the supplied size.
* The driver will copy the updated size into the
* original parameters.
*/
p->u.memref.shm = NULL;
p->u.memref.shm_offs = 0;
p->u.memref.size = ip.b;
break;
default:
memset(&p->u, 0, sizeof(p->u));
break;
}
}
return 0;
}