Skip to content

Commit d5b8b0f

Browse files
qc-azarrabijenswi-linaro
authored andcommitted
tee: add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF
The TEE subsystem allows session-based access to trusted services, requiring a session to be established to receive a service. This is not suitable for an environment that represents services as objects. An object supports various operations that a client can invoke, potentially generating a result or a new object that can be invoked independently of the original object. Add TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT/OUTPUT/INOUT to represent an object. Objects may reside in either TEE or userspace. To invoke an object in TEE, introduce a new ioctl. Use the existing SUPPL_RECV and SUPPL_SEND to invoke an object in userspace. Reviewed-by: Sumit Garg <sumit.garg@oss.qualcomm.com> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> Tested-by: Harshal Dev <quic_hdev@quicinc.com> Signed-off-by: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com> Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
1 parent 54a53e9 commit d5b8b0f

4 files changed

Lines changed: 130 additions & 6 deletions

File tree

drivers/tee/tee_core.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params,
487487
switch (ip.attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
488488
case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
489489
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
490+
case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT:
490491
break;
491492
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
492493
case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
@@ -505,6 +506,11 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params,
505506
return -EFAULT;
506507

507508
break;
509+
case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT:
510+
case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INOUT:
511+
params[n].u.objref.id = ip.a;
512+
params[n].u.objref.flags = ip.b;
513+
break;
508514
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
509515
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
510516
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
@@ -543,6 +549,12 @@ static int params_to_user(struct tee_ioctl_param __user *uparams,
543549
if (put_user((u64)p->u.ubuf.size, &up->b))
544550
return -EFAULT;
545551
break;
552+
case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT:
553+
case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INOUT:
554+
if (put_user(p->u.objref.id, &up->a) ||
555+
put_user(p->u.objref.flags, &up->b))
556+
return -EFAULT;
557+
break;
546558
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
547559
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
548560
if (put_user((u64)p->u.memref.size, &up->b))
@@ -695,6 +707,66 @@ static int tee_ioctl_invoke(struct tee_context *ctx,
695707
return rc;
696708
}
697709

710+
static int tee_ioctl_object_invoke(struct tee_context *ctx,
711+
struct tee_ioctl_buf_data __user *ubuf)
712+
{
713+
int rc;
714+
size_t n;
715+
struct tee_ioctl_buf_data buf;
716+
struct tee_ioctl_object_invoke_arg __user *uarg;
717+
struct tee_ioctl_object_invoke_arg arg;
718+
struct tee_ioctl_param __user *uparams = NULL;
719+
struct tee_param *params = NULL;
720+
721+
if (!ctx->teedev->desc->ops->object_invoke_func)
722+
return -EINVAL;
723+
724+
if (copy_from_user(&buf, ubuf, sizeof(buf)))
725+
return -EFAULT;
726+
727+
if (buf.buf_len > TEE_MAX_ARG_SIZE ||
728+
buf.buf_len < sizeof(struct tee_ioctl_object_invoke_arg))
729+
return -EINVAL;
730+
731+
uarg = u64_to_user_ptr(buf.buf_ptr);
732+
if (copy_from_user(&arg, uarg, sizeof(arg)))
733+
return -EFAULT;
734+
735+
if (sizeof(arg) + TEE_IOCTL_PARAM_SIZE(arg.num_params) != buf.buf_len)
736+
return -EINVAL;
737+
738+
if (arg.num_params) {
739+
params = kcalloc(arg.num_params, sizeof(struct tee_param),
740+
GFP_KERNEL);
741+
if (!params)
742+
return -ENOMEM;
743+
uparams = uarg->params;
744+
rc = params_from_user(ctx, params, arg.num_params, uparams);
745+
if (rc)
746+
goto out;
747+
}
748+
749+
rc = ctx->teedev->desc->ops->object_invoke_func(ctx, &arg, params);
750+
if (rc)
751+
goto out;
752+
753+
if (put_user(arg.ret, &uarg->ret)) {
754+
rc = -EFAULT;
755+
goto out;
756+
}
757+
rc = params_to_user(uparams, arg.num_params, params);
758+
out:
759+
if (params) {
760+
/* Decrease ref count for all valid shared memory pointers */
761+
for (n = 0; n < arg.num_params; n++)
762+
if (tee_param_is_memref(params + n) &&
763+
params[n].u.memref.shm)
764+
tee_shm_put(params[n].u.memref.shm);
765+
kfree(params);
766+
}
767+
return rc;
768+
}
769+
698770
static int tee_ioctl_cancel(struct tee_context *ctx,
699771
struct tee_ioctl_cancel_arg __user *uarg)
700772
{
@@ -750,6 +822,12 @@ static int params_to_supp(struct tee_context *ctx,
750822
ip.b = p->u.ubuf.size;
751823
ip.c = 0;
752824
break;
825+
case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT:
826+
case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INOUT:
827+
ip.a = p->u.objref.id;
828+
ip.b = p->u.objref.flags;
829+
ip.c = 0;
830+
break;
753831
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
754832
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
755833
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
@@ -862,6 +940,11 @@ static int params_from_supp(struct tee_param *params, size_t num_params,
862940
return -EFAULT;
863941

864942
break;
943+
case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT:
944+
case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INOUT:
945+
p->u.objref.id = ip.a;
946+
p->u.objref.flags = ip.b;
947+
break;
865948
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
866949
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
867950
/*
@@ -944,6 +1027,8 @@ static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
9441027
return tee_ioctl_open_session(ctx, uarg);
9451028
case TEE_IOC_INVOKE:
9461029
return tee_ioctl_invoke(ctx, uarg);
1030+
case TEE_IOC_OBJECT_INVOKE:
1031+
return tee_ioctl_object_invoke(ctx, uarg);
9471032
case TEE_IOC_CANCEL:
9481033
return tee_ioctl_cancel(ctx, uarg);
9491034
case TEE_IOC_CLOSE_SESSION:

include/linux/tee_core.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ struct tee_device {
8383
* @close_session: close a session
8484
* @system_session: declare session as a system session
8585
* @invoke_func: invoke a trusted function
86+
* @object_invoke_func: invoke a TEE object
8687
* @cancel_req: request cancel of an ongoing invoke or open
8788
* @supp_recv: called for supplicant to get a command
8889
* @supp_send: called for supplicant to send a response
@@ -108,6 +109,9 @@ struct tee_driver_ops {
108109
int (*invoke_func)(struct tee_context *ctx,
109110
struct tee_ioctl_invoke_arg *arg,
110111
struct tee_param *param);
112+
int (*object_invoke_func)(struct tee_context *ctx,
113+
struct tee_ioctl_object_invoke_arg *arg,
114+
struct tee_param *param);
111115
int (*cancel_req)(struct tee_context *ctx, u32 cancel_id, u32 session);
112116
int (*supp_recv)(struct tee_context *ctx, u32 *func, u32 *num_params,
113117
struct tee_param *param);

include/linux/tee_drv.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ struct tee_param_ubuf {
8787
size_t size;
8888
};
8989

90+
struct tee_param_objref {
91+
u64 id;
92+
u64 flags;
93+
};
94+
9095
struct tee_param_value {
9196
u64 a;
9297
u64 b;
@@ -97,6 +102,7 @@ struct tee_param {
97102
u64 attr;
98103
union {
99104
struct tee_param_memref memref;
105+
struct tee_param_objref objref;
100106
struct tee_param_ubuf ubuf;
101107
struct tee_param_value value;
102108
} u;

include/uapi/linux/tee.h

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@
4848
#define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */
4949
#define TEE_GEN_CAP_REG_MEM (1 << 2)/* Supports registering shared memory */
5050
#define TEE_GEN_CAP_MEMREF_NULL (1 << 3)/* NULL MemRef support */
51+
#define TEE_GEN_CAP_OBJREF (1 << 4)/* Supports generic object reference */
5152

52-
#define TEE_MEMREF_NULL (__u64)(-1) /* NULL MemRef Buffer */
53+
#define TEE_MEMREF_NULL ((__u64)(-1)) /* NULL MemRef Buffer */
54+
#define TEE_OBJREF_NULL ((__u64)(-1)) /* NULL ObjRef Object */
5355

5456
/*
5557
* TEE Implementation ID
@@ -158,6 +160,13 @@ struct tee_ioctl_buf_data {
158160
#define TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT 9
159161
#define TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT 10 /* input and output */
160162

163+
/*
164+
* These defines object reference parameters.
165+
*/
166+
#define TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INPUT 11
167+
#define TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT 12
168+
#define TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_INOUT 13
169+
161170
/*
162171
* Mask for the type part of the attribute, leaves room for more types
163172
*/
@@ -195,15 +204,16 @@ struct tee_ioctl_buf_data {
195204
* @attr: attributes
196205
* @a: if a memref, offset into the shared memory object,
197206
* else if a ubuf, address of the user buffer,
198-
* else a value parameter
199-
* @b: if a memref or ubuf, size of the buffer, else a value parameter
207+
* else if an objref, object identifier, else a value parameter
208+
* @b: if a memref or ubuf, size of the buffer,
209+
* else if objref, flags for the object, else a value parameter
200210
* @c: if a memref, shared memory identifier, else a value parameter
201211
*
202212
* @attr & TEE_PARAM_ATTR_TYPE_MASK indicates if memref, ubuf, or value is
203213
* used in the union. TEE_PARAM_ATTR_TYPE_VALUE_* indicates value,
204-
* TEE_PARAM_ATTR_TYPE_MEMREF_* indicates memref, and TEE_PARAM_ATTR_TYPE_UBUF_*
205-
* indicates ubuf. TEE_PARAM_ATTR_TYPE_NONE indicates that none of the members
206-
* are used.
214+
* TEE_PARAM_ATTR_TYPE_MEMREF_* indicates memref, TEE_PARAM_ATTR_TYPE_UBUF_*
215+
* indicates ubuf, and TEE_PARAM_ATTR_TYPE_OBJREF_* indicates objref.
216+
* TEE_PARAM_ATTR_TYPE_NONE indicates that none of the members are used.
207217
*
208218
* Shared memory is allocated with TEE_IOC_SHM_ALLOC which returns an
209219
* identifier representing the shared memory object. A memref can reference
@@ -442,4 +452,23 @@ struct tee_ioctl_shm_register_fd_data {
442452
* munmap(): unmaps previously shared memory
443453
*/
444454

455+
/**
456+
* struct tee_ioctl_invoke_func_arg - Invokes an object in a Trusted Application
457+
* @id: [in] Object id
458+
* @op: [in] Object operation, specific to the object
459+
* @ret: [out] return value
460+
* @num_params: [in] number of parameters following this struct
461+
*/
462+
struct tee_ioctl_object_invoke_arg {
463+
__u64 id;
464+
__u32 op;
465+
__u32 ret;
466+
__u32 num_params;
467+
/* num_params tells the actual number of element in params */
468+
struct tee_ioctl_param params[];
469+
};
470+
471+
#define TEE_IOC_OBJECT_INVOKE _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 10, \
472+
struct tee_ioctl_buf_data)
473+
445474
#endif /*__TEE_H*/

0 commit comments

Comments
 (0)