History

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.

Amirreza Zarrabi committed 1 year ago

Commit d5b8b0f1 parent 54a53e94 files · +130 −6Browse files

Unified · Split

4 files
  1. drivers/tee/tee_core.c +85 −0
  2. include/linux/tee_core.h +4 −0
  3. include/linux/tee_drv.h +6 −0
  4. include/uapi/linux/tee.h +35 −6
drivers/tee/tee_core.c+85−0
@@ -487,6 +487,7 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params, · 486 unmodified lines
487 switch (ip.attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {487 switch (ip.attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) {
488 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:488 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
489 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:489 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
490 case TEE_IOCTL_PARAM_ATTR_TYPE_OBJREF_OUTPUT:
490 break;491 break;
491 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:492 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
492 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:493 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, · 12 unmodified lines
505 return -EFAULT;506 return -EFAULT;
506 507
507 break;508 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;
508 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:514 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
509 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:515 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
510 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:516 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
@@ -543,6 +549,12 @@ static int params_to_user(struct tee_ioctl_param __user *uparams, · 32 unmodified lines
543 if (put_user((u64)p->u.ubuf.size, &up->b))549 if (put_user((u64)p->u.ubuf.size, &up->b))
544 return -EFAULT;550 return -EFAULT;
545 break;551 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;
546 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:558 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
547 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:559 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
548 if (put_user((u64)p->u.memref.size, &up->b))560 if (put_user((u64)p->u.memref.size, &up->b))
@@ -695,6 +707,66 @@ out: · 146 unmodified lines
695 return rc;707 return rc;
696}708}
697 709
710static 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);
758out:
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
698static int tee_ioctl_cancel(struct tee_context *ctx,770static int tee_ioctl_cancel(struct tee_context *ctx,
699 struct tee_ioctl_cancel_arg __user *uarg)771 struct tee_ioctl_cancel_arg __user *uarg)
700{772{
@@ -750,6 +822,12 @@ static int params_to_supp(struct tee_context *ctx, · 49 unmodified lines
750 ip.b = p->u.ubuf.size;822 ip.b = p->u.ubuf.size;
751 ip.c = 0;823 ip.c = 0;
752 break;824 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;
753 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:831 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
754 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:832 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
755 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:833 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, · 106 unmodified lines
862 return -EFAULT;940 return -EFAULT;
863 941
864 break;942 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;
865 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:948 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
866 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:949 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
867 /*950 /*
@@ -944,6 +1027,8 @@ static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) · 76 unmodified lines
944 return tee_ioctl_open_session(ctx, uarg);1027 return tee_ioctl_open_session(ctx, uarg);
945 case TEE_IOC_INVOKE:1028 case TEE_IOC_INVOKE:
946 return tee_ioctl_invoke(ctx, uarg);1029 return tee_ioctl_invoke(ctx, uarg);
1030 case TEE_IOC_OBJECT_INVOKE:
1031 return tee_ioctl_object_invoke(ctx, uarg);
947 case TEE_IOC_CANCEL:1032 case TEE_IOC_CANCEL:
948 return tee_ioctl_cancel(ctx, uarg);1033 return tee_ioctl_cancel(ctx, uarg);
949 case TEE_IOC_CLOSE_SESSION:1034 case TEE_IOC_CLOSE_SESSION:
include/linux/tee_core.h+4−0
@@ -83,6 +83,7 @@ struct tee_device { · 82 unmodified lines
83 * @close_session: close a session83 * @close_session: close a session
84 * @system_session: declare session as a system session84 * @system_session: declare session as a system session
85 * @invoke_func: invoke a trusted function85 * @invoke_func: invoke a trusted function
86 * @object_invoke_func: invoke a TEE object
86 * @cancel_req: request cancel of an ongoing invoke or open87 * @cancel_req: request cancel of an ongoing invoke or open
87 * @supp_recv: called for supplicant to get a command88 * @supp_recv: called for supplicant to get a command
88 * @supp_send: called for supplicant to send a response89 * @supp_send: called for supplicant to send a response
@@ -108,6 +109,9 @@ struct tee_driver_ops { · 19 unmodified lines
108 int (*invoke_func)(struct tee_context *ctx,109 int (*invoke_func)(struct tee_context *ctx,
109 struct tee_ioctl_invoke_arg *arg,110 struct tee_ioctl_invoke_arg *arg,
110 struct tee_param *param);111 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);
111 int (*cancel_req)(struct tee_context *ctx, u32 cancel_id, u32 session);115 int (*cancel_req)(struct tee_context *ctx, u32 cancel_id, u32 session);
112 int (*supp_recv)(struct tee_context *ctx, u32 *func, u32 *num_params,116 int (*supp_recv)(struct tee_context *ctx, u32 *func, u32 *num_params,
113 struct tee_param *param);117 struct tee_param *param);
include/linux/tee_drv.h+6−0
@@ -87,6 +87,11 @@ struct tee_param_ubuf { · 86 unmodified lines
87 size_t size;87 size_t size;
88};88};
89 89
90struct tee_param_objref {
91 u64 id;
92 u64 flags;
93};
94
90struct tee_param_value {95struct tee_param_value {
91 u64 a;96 u64 a;
92 u64 b;97 u64 b;
@@ -97,6 +102,7 @@ struct tee_param { · 4 unmodified lines
97 u64 attr;102 u64 attr;
98 union {103 union {
99 struct tee_param_memref memref;104 struct tee_param_memref memref;
105 struct tee_param_objref objref;
100 struct tee_param_ubuf ubuf;106 struct tee_param_ubuf ubuf;
101 struct tee_param_value value;107 struct tee_param_value value;
102 } u;108 } u;
include/uapi/linux/tee.h+35−6
@@ -48,8 +48,10 @@ · 47 unmodified lines
48#define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */48#define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */
49#define TEE_GEN_CAP_REG_MEM (1 << 2)/* Supports registering shared memory */49#define TEE_GEN_CAP_REG_MEM (1 << 2)/* Supports registering shared memory */
50#define TEE_GEN_CAP_MEMREF_NULL (1 << 3)/* NULL MemRef support */50#define TEE_GEN_CAP_MEMREF_NULL (1 << 3)/* NULL MemRef support */
51#define TEE_GEN_CAP_OBJREF (1 << 4)/* Supports generic object reference */
51 52
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 */
53 55
54/*56/*
55 * TEE Implementation ID57 * TEE Implementation ID
@@ -158,6 +160,13 @@ struct tee_ioctl_buf_data { · 102 unmodified lines
158#define TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT 9160#define TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT 9
159#define TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT 10 /* input and output */161#define TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT 10 /* input and output */
160 162
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
161/*170/*
162 * Mask for the type part of the attribute, leaves room for more types171 * Mask for the type part of the attribute, leaves room for more types
163 */172 */
@@ -195,15 +204,16 @@ struct tee_ioctl_buf_data { · 31 unmodified lines
195 * @attr: attributes204 * @attr: attributes
196 * @a: if a memref, offset into the shared memory object,205 * @a: if a memref, offset into the shared memory object,
197 * else if a ubuf, address of the user buffer,206 * else if a ubuf, address of the user buffer,
198 * else a value parameter207 * else if an objref, object identifier, else a value parameter
199 * @b: if a memref or ubuf, size of the buffer, else a value parameter208 * @b: if a memref or ubuf, size of the buffer,
209 * else if objref, flags for the object, else a value parameter
200 * @c: if a memref, shared memory identifier, else a value parameter210 * @c: if a memref, shared memory identifier, else a value parameter
201 *211 *
202 * @attr & TEE_PARAM_ATTR_TYPE_MASK indicates if memref, ubuf, or value is212 * @attr & TEE_PARAM_ATTR_TYPE_MASK indicates if memref, ubuf, or value is
203 * used in the union. TEE_PARAM_ATTR_TYPE_VALUE_* indicates value,213 * 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_*214 * TEE_PARAM_ATTR_TYPE_MEMREF_* indicates memref, TEE_PARAM_ATTR_TYPE_UBUF_*
205 * indicates ubuf. TEE_PARAM_ATTR_TYPE_NONE indicates that none of the members215 * indicates ubuf, and TEE_PARAM_ATTR_TYPE_OBJREF_* indicates objref.
206 * are used.216 * TEE_PARAM_ATTR_TYPE_NONE indicates that none of the members are used.
207 *217 *
208 * Shared memory is allocated with TEE_IOC_SHM_ALLOC which returns an218 * Shared memory is allocated with TEE_IOC_SHM_ALLOC which returns an
209 * identifier representing the shared memory object. A memref can reference219 * identifier representing the shared memory object. A memref can reference
@@ -442,4 +452,23 @@ struct tee_ioctl_shm_register_fd_data { · 232 unmodified lines
442 * munmap(): unmaps previously shared memory452 * munmap(): unmaps previously shared memory
443 */453 */
444 454
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 */
462struct 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
445#endif /*__TEE_H*/474#endif /*__TEE_H*/

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t