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
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, · 12 unmodified lines
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, · 32 unmodified lines
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 @@ out: · 146 unmodified lines
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, · 49 unmodified lines
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, · 106 unmodified lines
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) · 76 unmodified lines
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+4−0
@@ -83,6 +83,7 @@ struct tee_device { · 82 unmodified lines
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 { · 19 unmodified lines
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+6−0
@@ -87,6 +87,11 @@ struct tee_param_ubuf { · 86 unmodified lines
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 { · 4 unmodified lines
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+35−6
@@ -48,8 +48,10 @@ · 47 unmodified lines
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 { · 102 unmodified lines
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 { · 31 unmodified lines
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 { · 232 unmodified lines
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*/

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