1 /*
2 * Copyright (c) 2020-2022 The strace developers.
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7
8 #include "defs.h"
9 #include <linux/tee.h>
10
11 /* Not in UAPI. */
12 struct tee_ioctl_shm_register_fd_data {
13 int64_t fd;
14 uint64_t size;
15 uint32_t flags;
16 uint8_t _pad1[4];
17 int32_t id;
18 uint8_t _pad2[4];
19 } ATTRIBUTE_ALIGNED(8);
20
21 #define TEE_IOC_SHM_REGISTER_FD _IOWR(0xa4, 8, struct tee_ioctl_shm_register_fd_data)
22
23 #include "xlat/tee_ioctl_gen_caps.h"
24 #include "xlat/tee_ioctl_impl_ids.h"
25 #include "xlat/tee_ioctl_login_types.h"
26 #include "xlat/tee_ioctl_max_arg_size.h"
27 #include "xlat/tee_ioctl_origins.h"
28 #include "xlat/tee_ioctl_optee_caps.h"
29 #include "xlat/tee_ioctl_param_attr_types.h"
30 #include "xlat/tee_ioctl_shm_flags.h"
31
32 #define TEE_IOCTL_PARAM_SIZE(x) (sizeof(struct tee_ioctl_param) * (x))
33
34 #define TEE_FETCH_BUF_DATA(buf_, arg_, params_) \
35 tee_fetch_buf_data(tcp, arg, &buf_, sizeof(arg_), \
36 &arg_, offsetof(typeof(arg_), num_params), \
37 params_)
38
39 /* session id is printed as 0x%x in libteec */
40 #define PRINT_FIELD_SESSION(where_, field_) \
41 PRINT_FIELD_X(where_, field_)
42
43 static void
44 tee_print_buf(struct tee_ioctl_buf_data *buf)
45 {
46 tprint_struct_begin();
47 PRINT_FIELD_U(*buf, buf_len);
48 tprint_struct_next();
49 PRINT_FIELD_ADDR64(*buf, buf_ptr);
50 tprint_struct_end();
51 }
52
53 static int
54 tee_fetch_buf_data(struct tcb *const tcp,
55 const kernel_ulong_t arg,
56 struct tee_ioctl_buf_data *buf,
57 size_t arg_size,
58 void *arg_struct,
59 size_t num_params_offs,
60 uint64_t *params)
61 {
62 if (umove_or_printaddr(tcp, arg, buf))
63 return RVAL_IOCTL_DECODED;
64 if (buf->buf_len > TEE_MAX_ARG_SIZE || buf->buf_len < arg_size) {
65 tee_print_buf(buf);
66 return RVAL_IOCTL_DECODED;
67 }
68 if (umoven(tcp, buf->buf_ptr, arg_size, arg_struct)) {
69 tee_print_buf(buf);
70 return RVAL_IOCTL_DECODED;
71 }
72 uint32_t *num_params = (uint32_t *) (arg_struct + num_params_offs);
73 if (entering(tcp) &&
74 (arg_size + TEE_IOCTL_PARAM_SIZE(*num_params) != buf->buf_len)) {
75 /*
76 * We could print whatever number of params
77 * is in buf_data, but the kernel would ignore
78 * them anyway (and return -EINVAL) if
79 * the above condition is not satisfied.
80 *
81 * Except for on exiting. The kernel has the right
82 * to update num_params but not buf_len
83 * (see tee_ioctl_supp_recv)
84 */
85 tee_print_buf(buf);
86 return RVAL_IOCTL_DECODED;
87 }
88 if (*num_params) {
89 *params = buf->buf_ptr + arg_size;
90 } else {
91 *params = 0;
92 }
93
94 return 0;
95 }
96
97 static bool
98 tee_print_param_fn(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
99 {
100 struct tee_ioctl_param *param = (struct tee_ioctl_param *) elem_buf;
101
102 tprint_struct_begin();
103 tprints_field_name("attr");
104 tprint_flags_begin();
105 printxval(tee_ioctl_param_attr_types,
106 param->attr & ~TEE_IOCTL_PARAM_ATTR_META,
107 "TEE_IOCTL_PARAM_ATTR_");
108 if (param->attr & TEE_IOCTL_PARAM_ATTR_META) {
109 tprint_flags_or();
110 tprints_string("TEE_IOCTL_PARAM_ATTR_META");
111 }
112 tprint_flags_end();
113
114 switch (param->attr) {
115 case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
116 break;
117
118 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
119 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
120 case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
121 tprint_struct_next();
122 tprints_field_name("shm_offs");
123 PRINT_VAL_X(param->a);
124 tprint_struct_next();
125 tprints_field_name("size");
126 PRINT_VAL_X(param->b);
127 tprint_struct_next();
128 tprints_field_name("shm_id");
129 PRINT_VAL_U(param->c);
130 break;
131
132 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
133 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
134 case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
135 default:
136 tprint_struct_next();
137 PRINT_FIELD_X(*param, a);
138 tprint_struct_next();
139 PRINT_FIELD_X(*param, b);
140 tprint_struct_next();
141 PRINT_FIELD_X(*param, c);
142 break;
143 }
144 tprint_struct_end();
145 return true;
146 }
147
148 static void
149 tee_print_params(struct tcb *const tcp, uint64_t params_start, unsigned num_params)
150 {
151 struct tee_ioctl_param param_buffer;
152
153 tprint_struct_next();
154 tprints_field_name("params");
155 print_array(tcp, params_start, num_params, ¶m_buffer, sizeof(param_buffer),
156 tfetch_mem, tee_print_param_fn, NULL);
157 }
158
159 static int
160 tee_version(struct tcb *const tcp, const kernel_ulong_t arg)
161 {
162 struct tee_ioctl_version_data version;
163
164 if (entering(tcp)) {
165 tprint_arg_next();
166 return 0;
167 }
168
169 if (umove_or_printaddr(tcp, arg, &version))
170 return RVAL_IOCTL_DECODED;
171
172 tprint_struct_begin();
173 PRINT_FIELD_XVAL(version, impl_id,
174 tee_ioctl_impl_ids, "TEE_IMPL_ID_???");
175 tprint_struct_next();
176 PRINT_FIELD_FLAGS(version, gen_caps,
177 tee_ioctl_gen_caps, "TEE_GEN_CAP_???");
178 if (version.impl_id == TEE_IMPL_ID_OPTEE) {
179 tprint_struct_next();
180 PRINT_FIELD_FLAGS(version, impl_caps,
181 tee_ioctl_optee_caps, "TEE_OPTEE_CAP_???");
182 } else {
183 tprint_struct_next();
184 PRINT_FIELD_X(version, impl_caps);
185 }
186
187 tprint_struct_end();
188 return RVAL_IOCTL_DECODED;
189 }
190
191 static int
192 tee_open_session(struct tcb *const tcp, const kernel_ulong_t arg)
193 {
194 int rval;
195 struct tee_ioctl_buf_data buf_data;
196 struct tee_ioctl_open_session_arg open_session;
197 uint64_t params;
198 gid_t gid;
199
200 if (entering(tcp)) {
201 tprint_arg_next();
202
203 if ((rval = TEE_FETCH_BUF_DATA(buf_data, open_session, ¶ms)))
204 return rval;
205
206 tprint_struct_begin();
207 PRINT_FIELD_U(buf_data, buf_len);
208 tprint_struct_next();
209 tprints_field_name("buf_ptr");
210 tprint_struct_begin();
211 PRINT_FIELD_UUID(open_session, uuid);
212 tprint_struct_next();
213 PRINT_FIELD_XVAL(open_session, clnt_login,
214 tee_ioctl_login_types, "TEE_IOCTL_LOGIN_???");
215 /*
216 * tee_ioctl_open_session_arg.clnt_uuid is used to pass
217 * connectionData, which is currently only used to indicate
218 * which group the client application wishes to authenticate as
219 * (when TEE_IOCTL_LOGIN_GROUP or TEE_IOCTL_LOGIN_GROUP_APPLICATION
220 * are used).
221 *
222 * It is not an UUID; actual client UUID is computed in the kernel.
223 */
224 switch (open_session.clnt_login) {
225 case TEE_IOCTL_LOGIN_PUBLIC:
226 case TEE_IOCTL_LOGIN_USER:
227 case TEE_IOCTL_LOGIN_APPLICATION:
228 case TEE_IOCTL_LOGIN_USER_APPLICATION:
229 break;
230 case TEE_IOCTL_LOGIN_GROUP:
231 case TEE_IOCTL_LOGIN_GROUP_APPLICATION:
232 memcpy(&gid, open_session.clnt_uuid, sizeof(gid));
233 tprint_struct_next();
234 tprints_field_name("clnt_uuid");
235 printuid(gid);
236 break;
237 default:
238 tprint_struct_next();
239 PRINT_FIELD_X_ARRAY(open_session, clnt_uuid);
240 }
241 tprint_struct_next();
242 PRINT_FIELD_U(open_session, cancel_id);
243 tprint_struct_next();
244 PRINT_FIELD_U(open_session, num_params);
245 tee_print_params(tcp, params, open_session.num_params);
246
247 tprint_struct_end();
248 return 0;
249
250 } else if (syserror(tcp)) {
251 tprint_struct_end();
252 return RVAL_IOCTL_DECODED;
253
254 } else {
255 tprint_value_changed();
256 /*
257 * Yes, params are [in/out] for TEE_IOC_OPEN_SESSION.
258 * As for all other operations they are used in.
259 */
260 if ((rval = TEE_FETCH_BUF_DATA(buf_data, open_session, ¶ms)))
261 return rval;
262
263 tprint_struct_begin();
264 PRINT_FIELD_SESSION(open_session, session);
265 tprint_struct_next();
266 PRINT_FIELD_U(open_session, ret);
267 tprint_struct_next();
268 PRINT_FIELD_XVAL(open_session, ret_origin, tee_ioctl_origins,
269 "TEEC_ORIGIN_???");
270 tee_print_params(tcp, params, open_session.num_params);
271
272 tprint_struct_end();
273 tprint_struct_end();
274 return RVAL_IOCTL_DECODED;
275 }
276 }
277
278 static int
279 tee_invoke(struct tcb *const tcp, const kernel_ulong_t arg)
280 {
281 int rval;
282 struct tee_ioctl_buf_data buf_data;
283 struct tee_ioctl_invoke_arg invoke;
284 uint64_t params;
285
286 if (entering(tcp)) {
287 tprint_arg_next();
288 if ((rval = TEE_FETCH_BUF_DATA(buf_data, invoke, ¶ms)))
289 return rval;
290
291 tprint_struct_begin();
292 PRINT_FIELD_U(buf_data, buf_len);
293 tprint_struct_next();
294 tprints_field_name("buf_ptr");
295 tprint_struct_begin();
296 PRINT_FIELD_U(invoke, func);
297 tprint_struct_next();
298 PRINT_FIELD_SESSION(invoke, session);
299 tprint_struct_next();
300 PRINT_FIELD_U(invoke, cancel_id);
301 tprint_struct_next();
302 PRINT_FIELD_U(invoke, num_params);
303 tee_print_params(tcp, params, invoke.num_params);
304
305 tprint_struct_end();
306 return 0;
307
308 } else if (syserror(tcp)) {
309 tprint_struct_end();
310 return RVAL_IOCTL_DECODED;
311
312 } else {
313 tprint_value_changed();
314 if ((rval = TEE_FETCH_BUF_DATA(buf_data, invoke, ¶ms)))
315 return rval;
316
317 tprint_struct_begin();
318 PRINT_FIELD_U(invoke, ret);
319 tprint_struct_next();
320 PRINT_FIELD_XVAL(invoke, ret_origin, tee_ioctl_origins,
321 "TEEC_ORIGIN_???");
322 tee_print_params(tcp, params, invoke.num_params);
323
324 tprint_struct_end();
325 tprint_struct_end();
326 return RVAL_IOCTL_DECODED;
327 }
328 }
329
330 static int
331 tee_cancel(struct tcb *const tcp, const kernel_ulong_t arg)
332 {
333 struct tee_ioctl_cancel_arg cancel;
334
335 tprint_arg_next();
336 if (umove_or_printaddr(tcp, arg, &cancel))
337 return RVAL_IOCTL_DECODED;
338
339 tprint_struct_begin();
340 PRINT_FIELD_U(cancel, cancel_id);
341 tprint_struct_next();
342 PRINT_FIELD_SESSION(cancel, session);
343
344 tprint_struct_end();
345 return RVAL_IOCTL_DECODED;
346 }
347
348 static int
349 tee_close_session(struct tcb *const tcp, const kernel_ulong_t arg)
350 {
351 struct tee_ioctl_close_session_arg close_session;
352
353 tprint_arg_next();
354 if (umove_or_printaddr(tcp, arg, &close_session))
355 return RVAL_IOCTL_DECODED;
356
357 tprint_struct_begin();
358 PRINT_FIELD_SESSION(close_session, session);
359
360 tprint_struct_end();
361 return RVAL_IOCTL_DECODED;
362 }
363
364 static int
365 tee_suppl_recv(struct tcb *const tcp, const kernel_ulong_t arg)
366 {
367 int rval;
368 struct tee_ioctl_buf_data buf_data;
369 struct tee_iocl_supp_recv_arg supp_recv;
370 uint64_t params;
371
372 if (entering(tcp)) {
373 tprint_arg_next();
374 if ((rval = TEE_FETCH_BUF_DATA(buf_data, supp_recv, ¶ms)))
375 return rval;
376
377 tprint_struct_begin();
378 PRINT_FIELD_U(buf_data, buf_len);
379 tprint_struct_next();
380 tprints_field_name("buf_ptr");
381 tprint_struct_begin();
382 PRINT_FIELD_U(supp_recv, func);
383 tprint_struct_next();
384 PRINT_FIELD_U(supp_recv, num_params);
385 tee_print_params(tcp, params, supp_recv.num_params);
386
387 tprint_struct_end();
388 return 0;
389
390 } else if (syserror(tcp)) {
391 tprint_struct_end();
392 return RVAL_IOCTL_DECODED;
393
394 } else {
395 tprint_value_changed();
396 if ((rval = TEE_FETCH_BUF_DATA(buf_data, supp_recv, ¶ms)))
397 return rval;
398
399 /* num_params is [in/out] for TEE_IOC_SUPPL_RECV only */
400 tprint_struct_begin();
401 PRINT_FIELD_U(supp_recv, num_params);
402 tee_print_params(tcp, params, supp_recv.num_params);
403
404 tprint_struct_end();
405 tprint_struct_end();
406 return RVAL_IOCTL_DECODED;
407 }
408 }
409
410 static int
411 tee_suppl_send(struct tcb *const tcp, const kernel_ulong_t arg)
412 {
413 int rval;
414 struct tee_ioctl_buf_data buf_data;
415 struct tee_iocl_supp_send_arg supp_send;
416 uint64_t params;
417
418 if (entering(tcp)) {
419 tprint_arg_next();
420 if ((rval = TEE_FETCH_BUF_DATA(buf_data, supp_send, ¶ms)))
421 return rval;
422
423 tprint_struct_begin();
424 PRINT_FIELD_U(buf_data, buf_len);
425 tprint_struct_next();
426 tprints_field_name("buf_ptr");
427 tprint_struct_begin();
428 PRINT_FIELD_U(supp_send, num_params);
429 tee_print_params(tcp, params, supp_send.num_params);
430
431 tprint_struct_end();
432 return 0;
433
434 } else if (syserror(tcp)) {
435 tprint_struct_end();
436 return RVAL_IOCTL_DECODED;
437
438 } else {
439 tprint_value_changed();
440 if ((rval = TEE_FETCH_BUF_DATA(buf_data, supp_send, ¶ms)))
441 return rval;
442
443 tprint_struct_begin();
444 PRINT_FIELD_U(supp_send, ret);
445 tee_print_params(tcp, params, supp_send.num_params);
446
447 tprint_struct_end();
448 tprint_struct_end();
449 return RVAL_IOCTL_DECODED;
450 }
451 }
452
453 static int
454 tee_shm_alloc(struct tcb *const tcp, const kernel_ulong_t arg)
455 {
456 struct tee_ioctl_shm_alloc_data shm_alloc;
457
458 if (entering(tcp)) {
459 tprint_arg_next();
460 if (umove_or_printaddr(tcp, arg, &shm_alloc))
461 return RVAL_IOCTL_DECODED;
462
463 tprint_struct_begin();
464 PRINT_FIELD_X(shm_alloc, size);
465 tprint_struct_next();
466 PRINT_FIELD_FLAGS(shm_alloc, flags,
467 tee_ioctl_shm_flags, "TEE_IOCTL_SHM_???");
468 tprint_struct_end();
469 return 0;
470
471 } else if (syserror(tcp)) {
472 return RVAL_IOCTL_DECODED;
473
474 } else {
475 tprint_value_changed();
476 if (umove_or_printaddr(tcp, arg, &shm_alloc))
477 return RVAL_IOCTL_DECODED;
478
479 tprint_struct_begin();
480 PRINT_FIELD_X(shm_alloc, size);
481 tprint_struct_next();
482 PRINT_FIELD_FLAGS(shm_alloc, flags,
483 tee_ioctl_shm_flags, "TEE_IOCTL_SHM_???");
484 tprint_struct_next();
485 PRINT_FIELD_D(shm_alloc, id);
486
487 tprint_struct_end();
488 return RVAL_IOCTL_DECODED;
489 }
490 }
491
492 static int
493 tee_shm_register_fd(struct tcb *const tcp, const kernel_ulong_t arg)
494 {
495 struct tee_ioctl_shm_register_fd_data shm_register_fd;
496
497 if (entering(tcp)) {
498 tprint_arg_next();
499 if (umove_or_printaddr(tcp, arg, &shm_register_fd))
500 return RVAL_IOCTL_DECODED;
501
502 tprint_struct_begin();
503 PRINT_FIELD_FD(shm_register_fd, fd, tcp);
504 tprint_struct_next();
505 PRINT_FIELD_FLAGS(shm_register_fd, flags,
506 tee_ioctl_shm_flags, "TEE_IOCTL_SHM_???");
507 tprint_struct_end();
508 return 0;
509
510 } else if (syserror(tcp)) {
511 return RVAL_IOCTL_DECODED;
512
513 } else {
514 tprint_value_changed();
515 if (umove_or_printaddr(tcp, arg, &shm_register_fd))
516 return RVAL_IOCTL_DECODED;
517
518 tprint_struct_begin();
519 PRINT_FIELD_X(shm_register_fd, size);
520 tprint_struct_next();
521 PRINT_FIELD_D(shm_register_fd, id);
522
523 tprint_struct_end();
524 return RVAL_IOCTL_DECODED;
525 }
526 }
527
528 static int
529 tee_shm_register(struct tcb *const tcp, const kernel_ulong_t arg)
530 {
531 struct tee_ioctl_shm_register_data shm_register;
532
533 if (entering(tcp)) {
534 tprint_arg_next();
535 if (umove_or_printaddr(tcp, arg, &shm_register))
536 return RVAL_IOCTL_DECODED;
537
538 tprint_struct_begin();
539 PRINT_FIELD_ADDR64(shm_register, addr);
540 tprint_struct_next();
541 PRINT_FIELD_X(shm_register, length);
542 tprint_struct_next();
543 PRINT_FIELD_FLAGS(shm_register, flags,
544 tee_ioctl_shm_flags, "TEE_IOCTL_SHM_???");
545 tprint_struct_end();
546 return 0;
547
548 } else if (syserror(tcp)) {
549 return RVAL_IOCTL_DECODED;
550
551 } else {
552 tprint_value_changed();
553 if (umove_or_printaddr(tcp, arg, &shm_register))
554 return RVAL_IOCTL_DECODED;
555
556 tprint_struct_begin();
557 PRINT_FIELD_X(shm_register, length);
558 tprint_struct_next();
559 PRINT_FIELD_FLAGS(shm_register, flags,
560 tee_ioctl_shm_flags, "TEE_IOCTL_SHM_???");
561 tprint_struct_next();
562 PRINT_FIELD_D(shm_register, id);
563
564 tprint_struct_end();
565 return RVAL_IOCTL_DECODED;
566 }
567 }
568
569 int
570 tee_ioctl(struct tcb *const tcp, const unsigned int code,
571 const kernel_ulong_t arg)
572 {
573 switch (code) {
574 case TEE_IOC_VERSION:
575 return tee_version(tcp, arg);
576
577 case TEE_IOC_OPEN_SESSION:
578 return tee_open_session(tcp, arg);
579
580 case TEE_IOC_INVOKE:
581 return tee_invoke(tcp, arg);
582
583 case TEE_IOC_CANCEL:
584 return tee_cancel(tcp, arg);
585
586 case TEE_IOC_CLOSE_SESSION:
587 return tee_close_session(tcp, arg);
588
589 case TEE_IOC_SUPPL_RECV:
590 return tee_suppl_recv(tcp, arg);
591
592 case TEE_IOC_SUPPL_SEND:
593 return tee_suppl_send(tcp, arg);
594
595 case TEE_IOC_SHM_ALLOC:
596 return tee_shm_alloc(tcp, arg);
597
598 case TEE_IOC_SHM_REGISTER_FD:
599 /* This one isn't upstream */
600 return tee_shm_register_fd(tcp, arg);
601
602 case TEE_IOC_SHM_REGISTER:
603 return tee_shm_register(tcp, arg);
604
605 default:
606 return RVAL_DECODED;
607 }
608 }