1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Decription: function for session management.
4 *
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14 #include "session_manager.h"
15 #include <linux/slab.h>
16 #include <linux/types.h>
17 #include <linux/kernel.h>
18 #include <linux/file.h>
19 #include <linux/err.h>
20 #include <linux/fs.h>
21 #include <linux/spinlock_types.h>
22 #include <linux/spinlock.h>
23 #include <linux/uaccess.h>
24 #include <linux/sched.h>
25 #include <asm/cacheflush.h>
26 #include <linux/kthread.h>
27 #include <linux/atomic.h>
28 #include <linux/vmalloc.h>
29 #include <linux/pid.h>
30 #include <linux/cred.h>
31 #include <linux/thread_info.h>
32 #include <linux/highmem.h>
33 #include <linux/mm.h>
34 #if (KERNEL_VERSION(4, 14, 0) <= LINUX_VERSION_CODE)
35 #include <linux/sched/mm.h>
36 #include <linux/sched/signal.h>
37 #include <linux/sched/task.h>
38 #endif
39 #include <linux/completion.h>
40 #include <securec.h>
41 #include "smc_smp.h"
42 #include "mem.h"
43 #include "gp_ops.h"
44 #include "tc_ns_log.h"
45 #include "teek_client_constants.h"
46 #include "client_hash_auth.h"
47 #include "mailbox_mempool.h"
48 #include "tc_client_driver.h"
49 #include "internal_functions.h"
50 #include "dynamic_ion_mem.h"
51 #include "ko_adapt.h"
52
53 #ifdef CONFIG_CRL_PATH
54 #include "tz_update_crl.h"
55 uint8_t g_update_crl_flag = 0;
56 #endif
57
58 static DEFINE_MUTEX(g_load_app_lock);
59 #define MAX_REF_COUNT (255)
60
61 /* record all service node and need mutex to avoid race */
62 struct list_head g_service_list;
63 DEFINE_MUTEX(g_service_list_lock);
64
init_srvc_list(void)65 void init_srvc_list(void)
66 {
67 INIT_LIST_HEAD(&g_service_list);
68 }
69
get_session_struct(struct tc_ns_session * session)70 void get_session_struct(struct tc_ns_session *session)
71 {
72 if (!session)
73 return;
74
75 atomic_inc(&session->usage);
76 }
77
put_session_struct(struct tc_ns_session * session)78 void put_session_struct(struct tc_ns_session *session)
79 {
80 if (!session || !atomic_dec_and_test(&session->usage))
81 return;
82
83 if (memset_s(session, sizeof(*session), 0, sizeof(*session)) != 0)
84 tloge("Caution, memset failed!\n");
85 kfree(session);
86 }
87
get_service_struct(struct tc_ns_service * service)88 void get_service_struct(struct tc_ns_service *service)
89 {
90 if (!service)
91 return;
92
93 atomic_inc(&service->usage);
94 tlogd("service->usage = %d\n", atomic_read(&service->usage));
95 }
96
put_service_struct(struct tc_ns_service * service)97 void put_service_struct(struct tc_ns_service *service)
98 {
99 if (!service)
100 return;
101
102 tlogd("service->usage = %d\n", atomic_read(&service->usage));
103 mutex_lock(&g_service_list_lock);
104 if (atomic_dec_and_test(&service->usage)) {
105 tlogd("del service [0x%x] from service list\n",
106 *(uint32_t *)service->uuid);
107 list_del(&service->head);
108 kfree(service);
109 }
110 mutex_unlock(&g_service_list_lock);
111 }
112
add_service_to_dev(struct tc_ns_dev_file * dev,struct tc_ns_service * service)113 static int add_service_to_dev(struct tc_ns_dev_file *dev,
114 struct tc_ns_service *service)
115 {
116 uint32_t i;
117
118 if (!dev || !service)
119 return -EINVAL;
120
121 for (i = 0; i < SERVICES_MAX_COUNT; i++) {
122 if (!dev->services[i]) {
123 tlogd("add service %u to %u\n", i, dev->dev_file_id);
124 dev->services[i] = service;
125 dev->service_ref[i] = 1;
126 return 0;
127 }
128 }
129 return -EFAULT;
130 }
131
tz_srv_sess_dump(const char * param)132 static void tz_srv_sess_dump(const char *param)
133 {
134 struct tc_ns_smc_cmd smc_cmd = { {0}, 0 };
135
136 (void)param;
137 smc_cmd.cmd_id = GLOBAL_CMD_ID_DUMP_SRV_SESS;
138 smc_cmd.cmd_type = CMD_TYPE_GLOBAL;
139
140 livepatch_down_read_sem();
141 if (tc_ns_smc(&smc_cmd))
142 tloge("send dump service session failed\n");
143 livepatch_up_read_sem();
144 }
145
dump_services_status(const char * param)146 void dump_services_status(const char *param)
147 {
148 struct tc_ns_service *service = NULL;
149
150 (void)param;
151 mutex_lock(&g_service_list_lock);
152 tlogi("show service list:\n");
153 list_for_each_entry(service, &g_service_list, head) {
154 tlogi("uuid-%x, usage=%d\n", *(uint32_t *)service->uuid,
155 atomic_read(&service->usage));
156 }
157 mutex_unlock(&g_service_list_lock);
158
159 tz_srv_sess_dump(param);
160 }
161
del_service_from_dev(struct tc_ns_dev_file * dev,struct tc_ns_service * service)162 static void del_service_from_dev(struct tc_ns_dev_file *dev,
163 struct tc_ns_service *service)
164 {
165 uint32_t i;
166
167 for (i = 0; i < SERVICES_MAX_COUNT; i++) {
168 if (dev->services[i] == service) {
169 tlogd("dev service ref-%u = %u\n", i,
170 dev->service_ref[i]);
171 if (dev->service_ref[i] == 0) {
172 tloge("Caution! No service to be deleted!\n");
173 break;
174 }
175 dev->service_ref[i]--;
176 if (dev->service_ref[i] == 0) {
177 tlogd("del service %u from %u\n",
178 i, dev->dev_file_id);
179 dev->services[i] = NULL;
180 put_service_struct(service);
181 }
182 break;
183 }
184 }
185 }
186
tc_find_session_withowner(const struct list_head * session_list,unsigned int session_id,const struct tc_ns_dev_file * dev_file)187 struct tc_ns_session *tc_find_session_withowner(
188 const struct list_head *session_list,
189 unsigned int session_id, const struct tc_ns_dev_file *dev_file)
190 {
191 struct tc_ns_session *session = NULL;
192
193 if (!session_list || !dev_file) {
194 tloge("session list or dev is null\n");
195 return NULL;
196 }
197
198 list_for_each_entry(session, session_list, head) {
199 if (session->session_id == session_id &&
200 session->owner == dev_file)
201 return session;
202 }
203 return NULL;
204 }
205
tc_find_service_in_dev(const struct tc_ns_dev_file * dev,const unsigned char * uuid,int uuid_size)206 struct tc_ns_service *tc_find_service_in_dev(const struct tc_ns_dev_file *dev,
207 const unsigned char *uuid, int uuid_size)
208 {
209 uint32_t i;
210
211 if (!dev || !uuid || uuid_size != UUID_LEN)
212 return NULL;
213
214 for (i = 0; i < SERVICES_MAX_COUNT; i++) {
215 if (dev->services[i] != NULL &&
216 memcmp(dev->services[i]->uuid, uuid, UUID_LEN) == 0)
217 return dev->services[i];
218 }
219 return NULL;
220 }
221
tc_find_session_by_uuid(unsigned int dev_file_id,const struct tc_ns_smc_cmd * cmd)222 struct tc_ns_session *tc_find_session_by_uuid(unsigned int dev_file_id,
223 const struct tc_ns_smc_cmd *cmd)
224 {
225 struct tc_ns_dev_file *dev_file = NULL;
226 struct tc_ns_service *service = NULL;
227 struct tc_ns_session *session = NULL;
228
229 if (!cmd) {
230 tloge("parameter is null pointer!\n");
231 return NULL;
232 }
233
234 dev_file = tc_find_dev_file(dev_file_id);
235 if (!dev_file) {
236 tloge("can't find dev file!\n");
237 return NULL;
238 }
239
240 mutex_lock(&dev_file->service_lock);
241 service = tc_find_service_in_dev(dev_file, cmd->uuid, UUID_LEN);
242 get_service_struct(service);
243 mutex_unlock(&dev_file->service_lock);
244 if (!service) {
245 tloge("can't find service!\n");
246 return NULL;
247 }
248
249 mutex_lock(&service->session_lock);
250 session = tc_find_session_withowner(&service->session_list,
251 cmd->context_id, dev_file);
252 get_session_struct(session);
253 mutex_unlock(&service->session_lock);
254 put_service_struct(service);
255 if (!session) {
256 tloge("can't find session-0x%x!\n", cmd->context_id);
257 return NULL;
258 }
259 return session;
260 }
261
tc_ns_need_load_image(unsigned int file_id,const unsigned char * uuid,unsigned int uuid_len)262 static int tc_ns_need_load_image(unsigned int file_id,
263 const unsigned char *uuid, unsigned int uuid_len)
264 {
265 int ret;
266 int smc_ret;
267 struct tc_ns_smc_cmd smc_cmd = { {0}, 0 };
268 struct mb_cmd_pack *mb_pack = NULL;
269 char *mb_param = NULL;
270
271 if (!uuid || uuid_len != UUID_LEN) {
272 tloge("invalid uuid\n");
273 return -ENOMEM;
274 }
275 mb_pack = mailbox_alloc_cmd_pack();
276 if (!mb_pack) {
277 tloge("alloc mb pack failed\n");
278 return -ENOMEM;
279 }
280 mb_param = mailbox_copy_alloc(uuid, uuid_len);
281 if (!mb_param) {
282 tloge("alloc mb param failed\n");
283 ret = -ENOMEM;
284 goto clean;
285 }
286 mb_pack->operation.paramtypes = TEEC_MEMREF_TEMP_INOUT;
287 mb_pack->operation.params[0].memref.buffer =
288 mailbox_virt_to_phys((uintptr_t)mb_param);
289 mb_pack->operation.buffer_h_addr[0] =
290 (uint64_t)mailbox_virt_to_phys((uintptr_t)mb_param) >> ADDR_TRANS_NUM;
291 mb_pack->operation.params[0].memref.size = SZ_4K;
292 smc_cmd.cmd_id = GLOBAL_CMD_ID_NEED_LOAD_APP;
293 smc_cmd.cmd_type = CMD_TYPE_GLOBAL;
294 smc_cmd.dev_file_id = file_id;
295 smc_cmd.context_id = 0;
296 smc_cmd.operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation);
297 smc_cmd.operation_h_phys =
298 (uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM;
299
300 smc_ret = tc_ns_smc(&smc_cmd);
301 if (smc_ret != 0) {
302 tloge("smc call returns error ret 0x%x\n", smc_ret);
303 ret = -EFAULT;
304 goto clean;
305 } else {
306 ret = *(int *)mb_param;
307 }
308 clean:
309 if (mb_param)
310 mailbox_free(mb_param);
311 mailbox_free(mb_pack);
312
313 return ret;
314 }
315
tc_ns_load_secfile(struct tc_ns_dev_file * dev_file,void __user * argp,bool is_from_client_node)316 int tc_ns_load_secfile(struct tc_ns_dev_file *dev_file,
317 void __user *argp, bool is_from_client_node)
318 {
319 int ret;
320 struct load_secfile_ioctl_struct ioctl_arg = { {0}, {0}, {NULL} };
321 bool load = true;
322 void *file_addr = NULL;
323
324 if (!dev_file || !argp) {
325 tloge("Invalid params !\n");
326 return -EINVAL;
327 }
328
329 if (copy_from_user(&ioctl_arg, argp, sizeof(ioctl_arg)) != 0) {
330 tloge("copy from user failed\n");
331 ret = -ENOMEM;
332 return ret;
333 }
334
335 if (ioctl_arg.sec_file_info.secfile_type >= LOAD_TYPE_MAX ||
336 ioctl_arg.sec_file_info.secfile_type == LOAD_PATCH) {
337 tloge("invalid secfile type: %d!", ioctl_arg.sec_file_info.secfile_type);
338 return -EINVAL;
339 }
340
341 mutex_lock(&g_load_app_lock);
342 if (is_from_client_node) {
343 if (ioctl_arg.sec_file_info.secfile_type != LOAD_TA &&
344 ioctl_arg.sec_file_info.secfile_type != LOAD_LIB) {
345 tloge("this node does not allow this type of file to be loaded\n");
346 mutex_unlock(&g_load_app_lock);
347 return -EINVAL;
348 }
349 }
350
351 if (ioctl_arg.sec_file_info.secfile_type == LOAD_TA) {
352 ret = tc_ns_need_load_image(dev_file->dev_file_id, ioctl_arg.uuid, (unsigned int)UUID_LEN);
353 if (ret != 1) /* 1 means we need to load image */
354 load = false;
355 }
356
357 if (load) {
358 file_addr = (void *)(uintptr_t)(ioctl_arg.memref.file_addr |
359 (((uint64_t)ioctl_arg.memref.file_h_addr) << ADDR_TRANS_NUM));
360 ret = tc_ns_load_image(dev_file, file_addr, &ioctl_arg.sec_file_info, NULL);
361 if (ret != 0)
362 tloge("load TA secfile: %d failed, ret = 0x%x\n",
363 ioctl_arg.sec_file_info.secfile_type, ret);
364 }
365 mutex_unlock(&g_load_app_lock);
366 if (copy_to_user(argp, &ioctl_arg, sizeof(ioctl_arg)) != 0)
367 tloge("copy to user failed\n");
368 return ret;
369 }
370
tc_ns_get_uid(void)371 static uint32_t tc_ns_get_uid(void)
372 {
373 struct task_struct *task = NULL;
374 const struct cred *cred = NULL;
375 uint32_t uid;
376
377 rcu_read_lock();
378 task = get_current();
379 get_task_struct(task);
380 rcu_read_unlock();
381 cred = koadpt_get_task_cred(task);
382 if (!cred) {
383 tloge("failed to get uid of the task\n");
384 put_task_struct(task);
385 return (uint32_t)(-1);
386 }
387
388 uid = cred->uid.val;
389 put_cred(cred);
390 put_task_struct(task);
391 tlogd("current uid is %u\n", uid);
392 return uid;
393 }
394
395 #ifdef CONFIG_AUTH_SUPPORT_UNAME
set_login_information_uname(struct tc_ns_dev_file * dev_file,uint32_t uid)396 static int set_login_information_uname(struct tc_ns_dev_file *dev_file, uint32_t uid)
397 {
398 char uname[MAX_NAME_LENGTH] = { 0 };
399 uint32_t username_len = 0;
400 int ret = tc_ns_get_uname(uid, uname, sizeof(uname), &username_len);
401 if (ret < 0 || username_len >= MAX_NAME_LENGTH) {
402 tloge("get user name filed\n");
403 return -EFAULT;
404 }
405 if (memcpy_s(dev_file->pub_key, MAX_PUBKEY_LEN, uname, username_len)) {
406 tloge("failed to copy username, pub key len=%u\n", dev_file->pub_key_len);
407 return -EFAULT;
408 }
409 /* use pub_key to store username info */
410 dev_file->pub_key_len = username_len;
411 return 0;
412 }
413 #else
set_login_information_uid(struct tc_ns_dev_file * dev_file,uint32_t ca_uid)414 static int set_login_information_uid(struct tc_ns_dev_file *dev_file, uint32_t ca_uid)
415 {
416 if (memcpy_s(dev_file->pub_key, MAX_PUBKEY_LEN, &ca_uid, sizeof(ca_uid)) != 0) {
417 tloge("failed to copy pubkey, pub key len=%u\n",
418 dev_file->pub_key_len);
419 return -EFAULT;
420 }
421 dev_file->pub_key_len = sizeof(ca_uid);
422 return 0;
423 }
424 #endif
425
426 /*
427 * Modify the client context so params id 2 and 3 contain temp pointers to the
428 * public key and package name for the open session. This is used for the
429 * TEEC_LOGIN_IDENTIFY open session method
430 */
set_login_information(struct tc_ns_dev_file * dev_file,struct tc_ns_client_context * context)431 static int set_login_information(struct tc_ns_dev_file *dev_file,
432 struct tc_ns_client_context *context)
433 {
434 uint64_t size_addr, buffer_addr;
435 /* The daemon has failed to get login information or not supplied */
436 if (dev_file->pkg_name_len == 0)
437 return -EINVAL;
438 /*
439 * The 3rd parameter buffer points to the pkg name buffer in the
440 * device file pointer
441 * get package name len and package name
442 */
443 size_addr = (__u64)(uintptr_t)&dev_file->pkg_name_len;
444 buffer_addr = (__u64)(uintptr_t)dev_file->pkg_name;
445 context->params[3].memref.size_addr = (__u32)size_addr;
446 context->params[3].memref.size_h_addr = (__u32)(size_addr >> ADDR_TRANS_NUM);
447 context->params[3].memref.buffer = (__u32)buffer_addr;
448 context->params[3].memref.buffer_h_addr = (__u32)(buffer_addr >> ADDR_TRANS_NUM);
449
450 /* Set public key len and public key */
451 if (dev_file->pub_key_len == 0) {
452 /* If get public key failed, then get uid in kernel */
453 uint32_t ca_uid = tc_ns_get_uid();
454 if (ca_uid == (uint32_t)(-1)) {
455 tloge("failed to get uid of the task\n");
456 goto error;
457 }
458 #ifdef CONFIG_AUTH_SUPPORT_UNAME
459 if (set_login_information_uname(dev_file, ca_uid) != 0)
460 goto error;
461 #else
462 if (set_login_information_uid(dev_file, ca_uid) != 0)
463 goto error;
464 #endif
465 #ifdef CONFIG_AUTH_HASH
466 dev_file->pkg_name_len = strlen((unsigned char *)dev_file->pkg_name);
467 #endif
468 }
469 size_addr = (__u64)(uintptr_t)&dev_file->pub_key_len;
470 buffer_addr = (__u64)(uintptr_t)dev_file->pub_key;
471 context->params[2].memref.size_addr = (__u32)size_addr;
472 context->params[2].memref.size_h_addr = (__u32)(size_addr >> ADDR_TRANS_NUM);
473 context->params[2].memref.buffer = (__u32)buffer_addr;
474 context->params[2].memref.buffer_h_addr = (__u32)(buffer_addr >> ADDR_TRANS_NUM);
475 /* Now we mark the 2 parameters as input temp buffers */
476 context->param_types = teec_param_types(
477 teec_param_type_get(context->param_types, 0),
478 teec_param_type_get(context->param_types, 1),
479 TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_INPUT);
480 #ifdef CONFIG_AUTH_HASH
481 if(set_login_information_hash(dev_file) != 0) {
482 tloge("set login information hash failed\n");
483 goto error;
484 }
485 #endif
486 return 0;
487 error:
488 return -EFAULT;
489 }
490
check_login_method(struct tc_ns_dev_file * dev_file,struct tc_ns_client_context * context,uint8_t * flags)491 static int check_login_method(struct tc_ns_dev_file *dev_file,
492 struct tc_ns_client_context *context, uint8_t *flags)
493 {
494 int ret;
495
496 if (!dev_file || !context || !flags)
497 return -EFAULT;
498
499 if (is_tee_rebooting()) {
500 context->returns.code = TEE_ERROR_IS_DEAD;
501 /* when ret > 0, use context return code */
502 return EFAULT;
503 }
504
505 if (context->login.method != TEEC_LOGIN_IDENTIFY) {
506 tloge("login method is not supported\n");
507 return -EINVAL;
508 }
509
510 tlogd("login method is IDENTIFY\n");
511 /* check if usr params 0 and 1 are valid */
512 if (dev_file->kernel_api == TEE_REQ_FROM_USER_MODE &&
513 (!tc_user_param_valid(context, (unsigned int)0) ||
514 !tc_user_param_valid(context, (unsigned int)1)))
515 return -EINVAL;
516
517 ret = set_login_information(dev_file, context);
518 if (ret != 0) {
519 tloge("set login information failed ret =%d\n", ret);
520 return ret;
521 }
522 *flags |= TC_CALL_LOGIN;
523
524 return 0;
525 }
526
tc_ref_service_in_dev(struct tc_ns_dev_file * dev,const unsigned char * uuid,int uuid_size,bool * is_full)527 static struct tc_ns_service *tc_ref_service_in_dev(struct tc_ns_dev_file *dev,
528 const unsigned char *uuid, int uuid_size, bool *is_full)
529 {
530 uint32_t i;
531
532 if (uuid_size != UUID_LEN)
533 return NULL;
534
535 for (i = 0; i < SERVICES_MAX_COUNT; i++) {
536 if (dev->services[i] != NULL &&
537 memcmp(dev->services[i]->uuid, uuid, UUID_LEN) == 0) {
538 if (dev->service_ref[i] == MAX_REF_COUNT) {
539 *is_full = true;
540 return NULL;
541 }
542 dev->service_ref[i]++;
543 return dev->services[i];
544 }
545 }
546 return NULL;
547 }
548
tc_ns_service_init(const unsigned char * uuid,uint32_t uuid_len,struct tc_ns_service ** new_service)549 static int tc_ns_service_init(const unsigned char *uuid, uint32_t uuid_len,
550 struct tc_ns_service **new_service)
551 {
552 int ret = 0;
553 struct tc_ns_service *service = NULL;
554
555 if (!uuid || !new_service || uuid_len != UUID_LEN)
556 return -EINVAL;
557
558 service = kzalloc(sizeof(*service), GFP_KERNEL);
559 if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)service)) {
560 tloge("kzalloc failed\n");
561 ret = -ENOMEM;
562 return ret;
563 }
564
565 if (memcpy_s(service->uuid, sizeof(service->uuid), uuid, uuid_len) != 0) {
566 kfree(service);
567 return -EFAULT;
568 }
569
570 INIT_LIST_HEAD(&service->session_list);
571 mutex_init(&service->session_lock);
572 list_add_tail(&service->head, &g_service_list);
573 tlogd("add service: 0x%x to service list\n", *(const uint32_t *)uuid);
574 atomic_set(&service->usage, 1);
575 mutex_init(&service->operation_lock);
576 *new_service = service;
577
578 return ret;
579 }
580
tc_find_service_from_all(const unsigned char * uuid,uint32_t uuid_len)581 static struct tc_ns_service *tc_find_service_from_all(
582 const unsigned char *uuid, uint32_t uuid_len)
583 {
584 struct tc_ns_service *service = NULL;
585
586 if (!uuid || uuid_len != UUID_LEN)
587 return NULL;
588
589 list_for_each_entry(service, &g_service_list, head) {
590 if (memcmp(service->uuid, uuid, sizeof(service->uuid)) == 0)
591 return service;
592 }
593
594 return NULL;
595 }
596
find_service(struct tc_ns_dev_file * dev_file,const struct tc_ns_client_context * context)597 static struct tc_ns_service *find_service(struct tc_ns_dev_file *dev_file,
598 const struct tc_ns_client_context *context)
599 {
600 int ret;
601 struct tc_ns_service *service = NULL;
602 bool is_full = false;
603
604 mutex_lock(&dev_file->service_lock);
605 service = tc_ref_service_in_dev(dev_file, context->uuid,
606 UUID_LEN, &is_full);
607 /* if service has been opened in this dev or ref cnt is full */
608 if (service || is_full) {
609 /*
610 * If service has been reference by this dev, find service in dev
611 * will incre ref count to declaim there's how many callers to
612 * this service from the dev, instead of incre service->usage.
613 * While close session, dev->service_ref[i] will decre and till
614 * it get to 0, put service struct will be called.
615 */
616 mutex_unlock(&dev_file->service_lock);
617 return service;
618 }
619 mutex_lock(&g_service_list_lock);
620 service = tc_find_service_from_all(context->uuid, UUID_LEN);
621 /* if service has been opened in other dev */
622 if (service) {
623 get_service_struct(service);
624 mutex_unlock(&g_service_list_lock);
625 goto add_service;
626 }
627 /* Create a new service if we couldn't find it in list */
628 ret = tc_ns_service_init(context->uuid, UUID_LEN, &service);
629 /* unlock after init to make sure find service from all is correct */
630 mutex_unlock(&g_service_list_lock);
631 if (ret != 0) {
632 tloge("service init failed");
633 mutex_unlock(&dev_file->service_lock);
634 return NULL;
635 }
636 add_service:
637 ret = add_service_to_dev(dev_file, service);
638 mutex_unlock(&dev_file->service_lock);
639 if (ret != 0) {
640 /*
641 * for new srvc, match init usage to 1;
642 * for srvc already exist, match get;
643 */
644 put_service_struct(service);
645 service = NULL;
646 tloge("fail to add service to dev\n");
647 return NULL;
648 }
649 return service;
650 }
651
is_valid_ta_size(const char * file_buffer,unsigned int file_size)652 static bool is_valid_ta_size(const char *file_buffer, unsigned int file_size)
653 {
654 if (!file_buffer || file_size == 0) {
655 tloge("invalid load ta size\n");
656 return false;
657 }
658
659 if (file_size > SZ_8M) {
660 tloge("not support TA larger than 8M, size=%u\n", file_size);
661 return false;
662 }
663 return true;
664 }
665
alloc_for_load_image(struct load_img_params * params)666 static int alloc_for_load_image(struct load_img_params *params)
667 {
668 /* we will try any possible to alloc mailbox mem to load TA */
669 for (; params->mb_load_size > 0; params->mb_load_size >>= 1) {
670 params->mb_load_mem = mailbox_alloc(params->mb_load_size, 0);
671 if (params->mb_load_mem)
672 break;
673 tlogw("alloc mem size=%u for TA load mem fail\n",
674 params->mb_load_size);
675 }
676
677 if (!params->mb_load_mem) {
678 tloge("alloc TA load mem failed\n");
679 return -ENOMEM;
680 }
681
682 params->mb_pack = mailbox_alloc_cmd_pack();
683 if (!params->mb_pack) {
684 mailbox_free(params->mb_load_mem);
685 params->mb_load_mem = NULL;
686 tloge("alloc mb pack failed\n");
687 return -ENOMEM;
688 }
689
690 params->uuid_return = mailbox_alloc(sizeof(*(params->uuid_return)), 0);
691 if (!params->uuid_return) {
692 mailbox_free(params->mb_load_mem);
693 params->mb_load_mem = NULL;
694 mailbox_free(params->mb_pack);
695 params->mb_pack = NULL;
696 tloge("alloc uuid failed\n");
697 return -ENOMEM;
698 }
699 return 0;
700 }
701
pack_load_frame_cmd(uint32_t load_size,const struct load_img_params * params,struct tc_ns_smc_cmd * smc_cmd)702 static void pack_load_frame_cmd(uint32_t load_size,
703 const struct load_img_params *params, struct tc_ns_smc_cmd *smc_cmd)
704 {
705 struct mb_cmd_pack *mb_pack = params->mb_pack;
706 char *mb_load_mem = params->mb_load_mem;
707 struct tc_uuid *uuid_return = params->uuid_return;
708
709 mb_pack->operation.params[0].memref.buffer =
710 mailbox_virt_to_phys((uintptr_t)mb_load_mem);
711 mb_pack->operation.buffer_h_addr[0] =
712 (uint64_t)mailbox_virt_to_phys((uintptr_t)mb_load_mem) >> ADDR_TRANS_NUM;
713 mb_pack->operation.params[0].memref.size = load_size + sizeof(int);
714 mb_pack->operation.params[2].memref.buffer =
715 mailbox_virt_to_phys((uintptr_t)uuid_return);
716 mb_pack->operation.buffer_h_addr[2] =
717 (uint64_t)mailbox_virt_to_phys((uintptr_t)uuid_return) >> ADDR_TRANS_NUM;
718 mb_pack->operation.params[2].memref.size = sizeof(*uuid_return);
719 mb_pack->operation.paramtypes = teec_param_types(TEEC_MEMREF_TEMP_INPUT,
720 TEEC_VALUE_INOUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_VALUE_INOUT);
721
722 smc_cmd->cmd_type = CMD_TYPE_GLOBAL;
723 smc_cmd->cmd_id = GLOBAL_CMD_ID_LOAD_SECURE_APP;
724 smc_cmd->context_id = 0;
725 smc_cmd->operation_phys = mailbox_virt_to_phys((uintptr_t)&mb_pack->operation);
726 smc_cmd->operation_h_phys =
727 (uint64_t)mailbox_virt_to_phys((uintptr_t)&mb_pack->operation) >> ADDR_TRANS_NUM;
728 }
729
load_image_copy_file(struct load_img_params * params,uint32_t load_size,int32_t load_flag,uint32_t loaded_size)730 static int32_t load_image_copy_file(struct load_img_params *params, uint32_t load_size,
731 int32_t load_flag, uint32_t loaded_size)
732 {
733 if (params->dev_file->kernel_api == TEE_REQ_FROM_KERNEL_MODE) {
734 if (memcpy_s(params->mb_load_mem + sizeof(load_flag),
735 params->mb_load_size - sizeof(load_flag),
736 params->file_buffer + loaded_size, load_size) != 0) {
737 tloge("memcpy file buf get fail\n");
738 return -EFAULT;
739 }
740 return 0;
741 }
742 if (copy_from_user(params->mb_load_mem + sizeof(load_flag),
743 (const void __user *)params->file_buffer + loaded_size, load_size)) {
744 tloge("file buf get fail\n");
745 return -EFAULT;
746 }
747 return 0;
748 }
749
load_image_by_frame(struct load_img_params * params,unsigned int load_times,struct tc_ns_client_return * tee_ret,struct sec_file_info * sec_file_info)750 static int load_image_by_frame(struct load_img_params *params, unsigned int load_times,
751 struct tc_ns_client_return *tee_ret, struct sec_file_info *sec_file_info)
752 {
753 char *p = params->mb_load_mem;
754 uint32_t load_size;
755 int load_flag = 1; /* 0:it's last block, 1:not last block */
756 uint32_t loaded_size = 0;
757 unsigned int index;
758 struct tc_ns_smc_cmd smc_cmd = { {0}, 0 };
759 int smc_ret;
760
761 for (index = 0; index < load_times; index++) {
762 smc_cmd.err_origin = TEEC_ORIGIN_COMMS;
763 if (index == (load_times - 1)) {
764 load_flag = 0;
765 load_size = params->file_size - loaded_size;
766 } else {
767 load_size = params->mb_load_size - sizeof(load_flag);
768 }
769 *(int *)p = load_flag;
770 if (load_size > params->mb_load_size - sizeof(load_flag)) {
771 tloge("invalid load size %u/%u\n", load_size,
772 params->mb_load_size);
773 return -EINVAL;
774 }
775
776 if (load_image_copy_file(params, load_size, load_flag, loaded_size) != 0)
777 return -EFAULT;
778
779 pack_load_frame_cmd(load_size, params, &smc_cmd);
780 params->mb_pack->operation.params[3].value.a = index;
781 params->mb_pack->operation.params[1].value.a = sec_file_info->secfile_type;
782 smc_cmd.dev_file_id = params->dev_file->dev_file_id;
783 smc_ret = tc_ns_smc(&smc_cmd);
784 tlogd("configid=%u, ret=%d, load_flag=%d, index=%u\n",
785 params->mb_pack->operation.params[1].value.a, smc_ret,
786 load_flag, index);
787
788 if (smc_ret != 0) {
789 if (tee_ret != NULL) {
790 tee_ret->code = smc_ret;
791 tee_ret->origin = smc_cmd.err_origin;
792 }
793 sec_file_info->sec_load_err = (int32_t)params->mb_pack->operation.params[3].value.b;
794 return -EFAULT;
795 }
796
797 if (!smc_ret && !load_flag && load_image_for_ion(params, tee_ret ? &tee_ret->origin : NULL))
798 return -EPERM;
799
800 loaded_size += load_size;
801 }
802 return 0;
803 }
804
tc_ns_load_image_with_lock(struct tc_ns_dev_file * dev,const char * file_buffer,unsigned int file_size,enum secfile_type_t type)805 int tc_ns_load_image_with_lock(struct tc_ns_dev_file *dev, const char *file_buffer,
806 unsigned int file_size, enum secfile_type_t type)
807 {
808 int ret;
809 struct sec_file_info sec_file = {0, 0, 0};
810
811 if (!dev || !file_buffer) {
812 tloge("dev or file buffer is NULL!\n");
813 return -EINVAL;
814 }
815
816 sec_file.secfile_type = type;
817 sec_file.file_size = file_size;
818
819 mutex_lock(&g_load_app_lock);
820 ret = tc_ns_load_image(dev, file_buffer, &sec_file, NULL);
821 mutex_unlock(&g_load_app_lock);
822
823 return ret;
824 }
825
free_load_image_buffer(struct load_img_params * params)826 static void free_load_image_buffer(struct load_img_params *params)
827 {
828 mailbox_free(params->mb_load_mem);
829 mailbox_free(params->mb_pack);
830 mailbox_free(params->uuid_return);
831 }
832
load_image(struct load_img_params * params,struct sec_file_info * sec_file_info,struct tc_ns_client_return * tee_ret)833 int load_image(struct load_img_params *params,
834 struct sec_file_info *sec_file_info, struct tc_ns_client_return *tee_ret)
835 {
836 int ret;
837 unsigned int load_times;
838 unsigned int file_size;
839
840 /* tee_ret can be null */
841 if (params == NULL || sec_file_info == NULL)
842 return -1;
843
844 file_size = params->file_size;
845
846 params->mb_load_size = (file_size > (SZ_1M - sizeof(int))) ?
847 SZ_1M : ALIGN(file_size, SZ_4K);
848
849 ret = alloc_for_load_image(params);
850 if (ret != 0) {
851 tloge("Alloc load image buf fail!\n");
852 return ret;
853 }
854
855 if (params->mb_load_size <= sizeof(int)) {
856 tloge("mb load size is too small!\n");
857 free_load_image_buffer(params);
858 return -ENOMEM;
859 }
860
861 load_times = file_size / (params->mb_load_size - sizeof(int));
862 if ((file_size % (params->mb_load_size - sizeof(int))) != 0)
863 load_times += 1;
864
865 ret = load_image_by_frame(params, load_times, tee_ret, sec_file_info);
866 if (ret != 0) {
867 tloge("load image by frame fail!\n");
868 free_load_image_buffer(params);
869 return ret;
870 }
871
872 free_load_image_buffer(params);
873 return 0;
874 }
875
tc_ns_load_image(struct tc_ns_dev_file * dev,const char * file_buffer,struct sec_file_info * sec_file_info,struct tc_ns_client_return * tee_ret)876 int tc_ns_load_image(struct tc_ns_dev_file *dev, const char *file_buffer,
877 struct sec_file_info *sec_file_info, struct tc_ns_client_return *tee_ret)
878 {
879 int ret;
880 unsigned int file_size;
881 struct load_img_params params = { dev, file_buffer, 0, NULL, NULL, NULL, 0 };
882
883 if (!dev || !file_buffer || !sec_file_info) {
884 tloge("dev or file buffer or sec_file_info is NULL!\n");
885 return -EINVAL;
886 }
887
888 file_size = sec_file_info->file_size;
889 params.file_size = file_size;
890 #ifdef CONFIG_CRL_PATH
891 if (g_update_crl_flag == 0) {
892 if (tz_update_crl(CONFIG_CRL_PATH, dev) != 0) {
893 tloge("tzdriver updates main crl failed\n");
894 if (tz_update_crl(CONFIG_CRL_BAK_PATH, dev) != 0) {
895 tloge("tzdriver updates backup crl failed\n");
896 } else {
897 g_update_crl_flag = 1;
898 tloge("tzdriver updates backup crl successfully\n");
899 }
900 } else {
901 g_update_crl_flag = 1;
902 tloge("tzdriver updates main crl successfully\n");
903 }
904 }
905 #endif
906
907 if (!is_valid_ta_size(file_buffer, file_size))
908 return -EINVAL;
909
910 return load_image(¶ms, sec_file_info, tee_ret);
911 }
912
load_ta_image(struct tc_ns_dev_file * dev_file,struct tc_ns_client_context * context)913 static int load_ta_image(struct tc_ns_dev_file *dev_file,
914 struct tc_ns_client_context *context)
915 {
916 int ret;
917 struct sec_file_info sec_file = {0, 0, 0};
918 struct tc_ns_client_return tee_ret = {0};
919 void *file_addr = NULL;
920
921 tee_ret.origin = TEEC_ORIGIN_COMMS;
922
923 mutex_lock(&g_load_app_lock);
924 ret = tc_ns_need_load_image(dev_file->dev_file_id, context->uuid, (unsigned int)UUID_LEN);
925 if (ret == 1) { /* 1 means we need to load image */
926 if (!context->file_buffer) {
927 tloge("context's file_buffer is NULL");
928 mutex_unlock(&g_load_app_lock);
929 return -1;
930 }
931 file_addr = (void *)(uintptr_t)(context->memref.file_addr |
932 (((uint64_t)context->memref.file_h_addr) << ADDR_TRANS_NUM));
933 sec_file.secfile_type = LOAD_TA;
934 sec_file.file_size = context->file_size;
935 ret = tc_ns_load_image(dev_file, file_addr, &sec_file, &tee_ret);
936 if (ret != 0) {
937 tloge("load image failed, ret=%x", ret);
938 context->returns.code = tee_ret.code;
939 if (tee_ret.origin != TEEC_ORIGIN_COMMS) {
940 context->returns.origin = tee_ret.origin;
941 ret = EFAULT;
942 }
943 mutex_unlock(&g_load_app_lock);
944 return ret;
945 }
946 }
947 mutex_unlock(&g_load_app_lock);
948
949 return ret;
950 }
951
init_new_sess_node(struct tc_ns_dev_file * dev_file,const struct tc_ns_client_context * context,struct tc_ns_service * service,struct tc_ns_session * session)952 static void init_new_sess_node(struct tc_ns_dev_file *dev_file,
953 const struct tc_ns_client_context *context,
954 struct tc_ns_service *service,
955 struct tc_ns_session *session)
956 {
957 session->session_id = context->session_id;
958 atomic_set(&session->usage, 1);
959 session->owner = dev_file;
960
961 session->wait_data.send_wait_flag = 0;
962 init_waitqueue_head(&session->wait_data.send_cmd_wq);
963
964 mutex_lock(&service->session_lock);
965 list_add_tail(&session->head, &service->session_list);
966 mutex_unlock(&service->session_lock);
967 }
968
proc_open_session(struct tc_ns_dev_file * dev_file,struct tc_ns_client_context * context,struct tc_ns_service * service,struct tc_ns_session * session,uint8_t flags)969 static int proc_open_session(struct tc_ns_dev_file *dev_file,
970 struct tc_ns_client_context *context, struct tc_ns_service *service,
971 struct tc_ns_session *session, uint8_t flags)
972 {
973 int ret;
974 struct tc_call_params params = {
975 dev_file, context, session, flags
976 };
977
978 mutex_lock(&service->operation_lock);
979 ret = load_ta_image(dev_file, context);
980 if (ret != 0) {
981 tloge("load ta image failed\n");
982 mutex_unlock(&service->operation_lock);
983 return ret;
984 }
985
986 ret = tc_client_call(¶ms);
987 if (ret != 0) {
988 /* Clean this session secure information */
989 kill_ion_by_uuid((struct tc_uuid *)context->uuid);
990 mutex_unlock(&service->operation_lock);
991 tloge("smc call returns error, ret=0x%x\n", ret);
992 return ret;
993 }
994 init_new_sess_node(dev_file, context, service, session);
995 /*
996 * session_id in tee is unique, but in concurrency scene
997 * same session_id may appear in tzdriver, put session_list
998 * add/del in service->operation_lock can avoid it.
999 */
1000 mutex_unlock(&service->operation_lock);
1001 return ret;
1002 }
1003
clear_context_param(struct tc_ns_client_context * context)1004 static void clear_context_param(struct tc_ns_client_context *context)
1005 {
1006 context->params[2].memref.size_addr = 0;
1007 context->params[2].memref.size_h_addr = 0;
1008 context->params[2].memref.buffer = 0;
1009 context->params[2].memref.buffer_h_addr = 0;
1010 context->params[3].memref.size_addr = 0;
1011 context->params[3].memref.size_h_addr = 0;
1012 context->params[3].memref.buffer = 0;
1013 context->params[3].memref.buffer_h_addr = 0;
1014 }
1015
tc_ns_open_session(struct tc_ns_dev_file * dev_file,struct tc_ns_client_context * context)1016 int tc_ns_open_session(struct tc_ns_dev_file *dev_file,
1017 struct tc_ns_client_context *context)
1018 {
1019 int ret;
1020 struct tc_ns_service *service = NULL;
1021 struct tc_ns_session *session = NULL;
1022 uint8_t flags = TC_CALL_GLOBAL;
1023
1024 if (!dev_file || !context) {
1025 tloge("invalid dev_file or context\n");
1026 return -EINVAL;
1027 }
1028
1029 ret = check_login_method(dev_file, context, &flags);
1030 if (ret != 0)
1031 goto err_clear_param;
1032
1033 context->cmd_id = GLOBAL_CMD_ID_OPEN_SESSION;
1034
1035 service = find_service(dev_file, context);
1036 if (!service) {
1037 tloge("find service failed\n");
1038 ret = -ENOMEM;
1039 goto err_clear_param;
1040 }
1041
1042 session = kzalloc(sizeof(*session), GFP_KERNEL);
1043 if (ZERO_OR_NULL_PTR((unsigned long)(uintptr_t)session)) {
1044 tloge("kzalloc failed\n");
1045 mutex_lock(&dev_file->service_lock);
1046 del_service_from_dev(dev_file, service);
1047 mutex_unlock(&dev_file->service_lock);
1048 ret = -ENOMEM;
1049 goto err_clear_param;
1050 }
1051 mutex_init(&session->ta_session_lock);
1052
1053 #ifndef CONFIG_LIBLINUX
1054 ret = calc_client_auth_hash(dev_file, context, session);
1055 if (ret != 0) {
1056 tloge("calc client auth hash failed\n");
1057 goto err_free_rsrc;
1058 }
1059 #endif
1060
1061 ret = proc_open_session(dev_file, context, service, session, flags);
1062 if (ret == 0)
1063 goto err_clear_param;
1064 err_free_rsrc:
1065 mutex_lock(&dev_file->service_lock);
1066 del_service_from_dev(dev_file, service);
1067 mutex_unlock(&dev_file->service_lock);
1068
1069 kfree(session);
1070 err_clear_param:
1071 clear_context_param(context);
1072 return ret;
1073 }
1074
get_session(struct tc_ns_service * service,const struct tc_ns_dev_file * dev_file,const struct tc_ns_client_context * context)1075 static struct tc_ns_session *get_session(struct tc_ns_service *service,
1076 const struct tc_ns_dev_file *dev_file,
1077 const struct tc_ns_client_context *context)
1078 {
1079 struct tc_ns_session *session = NULL;
1080
1081 mutex_lock(&service->session_lock);
1082 session = tc_find_session_withowner(&service->session_list,
1083 context->session_id, dev_file);
1084 get_session_struct(session);
1085 mutex_unlock(&service->session_lock);
1086
1087 return session;
1088 }
1089
get_service(struct tc_ns_dev_file * dev_file,const struct tc_ns_client_context * context)1090 static struct tc_ns_service *get_service(struct tc_ns_dev_file *dev_file,
1091 const struct tc_ns_client_context *context)
1092 {
1093 struct tc_ns_service *service = NULL;
1094
1095 mutex_lock(&dev_file->service_lock);
1096 service = tc_find_service_in_dev(dev_file, context->uuid, UUID_LEN);
1097 get_service_struct(service);
1098 mutex_unlock(&dev_file->service_lock);
1099
1100 return service;
1101 }
1102
close_session(struct tc_ns_dev_file * dev,struct tc_ns_session * session,const unsigned char * uuid,unsigned int uuid_len,unsigned int session_id)1103 static int close_session(struct tc_ns_dev_file *dev,
1104 struct tc_ns_session *session, const unsigned char *uuid,
1105 unsigned int uuid_len, unsigned int session_id)
1106 {
1107 struct tc_ns_client_context context;
1108 int ret;
1109 struct tc_call_params params = {
1110 dev, &context, session, 0
1111 };
1112
1113 if (uuid_len != UUID_LEN)
1114 return -EINVAL;
1115
1116 if (memset_s(&context, sizeof(context), 0, sizeof(context)) != 0)
1117 return -EFAULT;
1118
1119 if (memcpy_s(context.uuid, sizeof(context.uuid), uuid, uuid_len) != 0)
1120 return -EFAULT;
1121
1122 context.session_id = session_id;
1123 context.cmd_id = GLOBAL_CMD_ID_CLOSE_SESSION;
1124 params.flags = TC_CALL_GLOBAL | TC_CALL_SYNC;
1125 ret = tc_client_call(¶ms);
1126 if (ret != 0)
1127 tloge("close session failed, ret=0x%x\n", ret);
1128
1129 kill_ion_by_uuid((struct tc_uuid *)context.uuid);
1130 return ret;
1131 }
1132
close_session_in_service_list(struct tc_ns_dev_file * dev,struct tc_ns_service * service)1133 static void close_session_in_service_list(struct tc_ns_dev_file *dev,
1134 struct tc_ns_service *service)
1135 {
1136 struct tc_ns_session *tmp_session = NULL;
1137 struct tc_ns_session *session = NULL;
1138 int ret;
1139
1140 list_for_each_entry_safe(session, tmp_session,
1141 &service->session_list, head) {
1142 if (session->owner != dev)
1143 continue;
1144 ret = close_session(dev, session, service->uuid,
1145 (unsigned int)UUID_LEN, session->session_id);
1146 if (ret != 0)
1147 tloge("close session smc failed when close fd!\n");
1148 mutex_lock(&service->session_lock);
1149 list_del(&session->head);
1150 mutex_unlock(&service->session_lock);
1151
1152 put_session_struct(session); /* pair with open session */
1153 }
1154 }
1155
if_exist_unclosed_session(struct tc_ns_dev_file * dev)1156 static bool if_exist_unclosed_session(struct tc_ns_dev_file *dev)
1157 {
1158 uint32_t index;
1159
1160 for (index = 0; index < SERVICES_MAX_COUNT; index++) {
1161 if (dev->services[index] != NULL &&
1162 list_empty(&dev->services[index]->session_list) == 0)
1163 return true;
1164 }
1165 return false;
1166 }
1167
close_session_thread_fn(void * arg)1168 static int close_session_thread_fn(void *arg)
1169 {
1170 struct tc_ns_dev_file *dev = arg;
1171 uint32_t index;
1172 struct tc_ns_service *service = NULL;
1173
1174 /* close unclosed session */
1175 for (index = 0; index < SERVICES_MAX_COUNT; index++) {
1176 if (dev->services[index] != NULL &&
1177 list_empty(&dev->services[index]->session_list) == 0) {
1178 service = dev->services[index];
1179
1180 mutex_lock(&service->operation_lock);
1181 close_session_in_service_list(dev, service);
1182 mutex_unlock(&service->operation_lock);
1183
1184 put_service_struct(service); /* pair with open session */
1185 }
1186 }
1187
1188 tlogd("complete close all unclosed session\n");
1189 complete(&dev->close_comp);
1190 return 0;
1191 }
1192
close_unclosed_session_in_kthread(struct tc_ns_dev_file * dev)1193 void close_unclosed_session_in_kthread(struct tc_ns_dev_file *dev)
1194 {
1195 struct task_struct *close_thread = NULL;
1196
1197 if (!dev) {
1198 tloge("dev is invalid\n");
1199 return;
1200 }
1201
1202 if (!if_exist_unclosed_session(dev))
1203 return;
1204
1205 /* when self recovery, release session in reboot interface */
1206 if (is_tee_rebooting())
1207 return;
1208 close_thread = kthread_create(close_session_thread_fn,
1209 dev, "close_fn_%6d", dev->dev_file_id);
1210 if (unlikely(IS_ERR_OR_NULL(close_thread))) {
1211 tloge("fail to create close session thread\n");
1212 return;
1213 }
1214
1215 tz_kthread_bind_mask(close_thread);
1216 wake_up_process(close_thread);
1217 wait_for_completion(&dev->close_comp);
1218 tlogd("wait for completion success\n");
1219 }
1220
tc_ns_close_session(struct tc_ns_dev_file * dev_file,struct tc_ns_client_context * context)1221 int tc_ns_close_session(struct tc_ns_dev_file *dev_file,
1222 struct tc_ns_client_context *context)
1223 {
1224 int ret = -EINVAL;
1225 struct tc_ns_service *service = NULL;
1226 struct tc_ns_session *session = NULL;
1227
1228 if (!dev_file || !context) {
1229 tloge("invalid dev_file or context\n");
1230 return ret;
1231 }
1232
1233 if (is_tee_rebooting()) {
1234 context->returns.code = TEE_ERROR_IS_DEAD;
1235 return TEE_ERROR_IS_DEAD;
1236 }
1237
1238 service = get_service(dev_file, context);
1239 if (!service) {
1240 tloge("invalid service\n");
1241 return ret;
1242 }
1243 /*
1244 * session_id in tee is unique, but in concurrency scene
1245 * same session_id may appear in tzdriver, put session_list
1246 * add/del in service->operation_lock can avoid it.
1247 */
1248 mutex_lock(&service->operation_lock);
1249 session = get_session(service, dev_file, context);
1250 if (session) {
1251 int ret2;
1252 mutex_lock(&session->ta_session_lock);
1253 ret2 = close_session(dev_file, session, context->uuid,
1254 (unsigned int)UUID_LEN, context->session_id);
1255 mutex_unlock(&session->ta_session_lock);
1256 if (ret2 != 0)
1257 tloge("close session smc failed!\n");
1258 mutex_lock(&service->session_lock);
1259 list_del(&session->head);
1260 mutex_unlock(&service->session_lock);
1261
1262 put_session_struct(session);
1263 put_session_struct(session); /* pair with open session */
1264
1265 ret = 0;
1266 mutex_lock(&dev_file->service_lock);
1267 del_service_from_dev(dev_file, service);
1268 mutex_unlock(&dev_file->service_lock);
1269 } else {
1270 tloge("invalid session\n");
1271 }
1272 mutex_unlock(&service->operation_lock);
1273 put_service_struct(service);
1274 return ret;
1275 }
1276
tc_ns_send_cmd(struct tc_ns_dev_file * dev_file,struct tc_ns_client_context * context)1277 int tc_ns_send_cmd(struct tc_ns_dev_file *dev_file,
1278 struct tc_ns_client_context *context)
1279 {
1280 int ret = -EINVAL;
1281 struct tc_ns_service *service = NULL;
1282 struct tc_ns_session *session = NULL;
1283 struct tc_call_params params = {
1284 dev_file, context, NULL, 0
1285 };
1286
1287 if (!dev_file || !context) {
1288 tloge("invalid dev_file or context\n");
1289 return ret;
1290 }
1291
1292 if (is_tee_rebooting()) {
1293 context->returns.code = TEE_ERROR_IS_DEAD;
1294 return EFAULT;
1295 }
1296
1297 service = get_service(dev_file, context);
1298 if (service) {
1299 session = get_session(service, dev_file, context);
1300 put_service_struct(service);
1301 if (session) {
1302 tlogd("send cmd find session id %x\n",
1303 context->session_id);
1304 goto find_session;
1305 }
1306 tloge("can't find session\n");
1307 } else {
1308 tloge("can't find service\n");
1309 }
1310
1311 return ret;
1312 find_session:
1313 mutex_lock(&session->ta_session_lock);
1314 params.sess = session;
1315 ret = tc_client_call(¶ms);
1316 mutex_unlock(&session->ta_session_lock);
1317 put_session_struct(session);
1318 if (ret != 0)
1319 tloge("smc call returns error, ret=0x%x\n", ret);
1320 return ret;
1321 }
1322
ioctl_session_send_cmd(struct tc_ns_dev_file * dev_file,struct tc_ns_client_context * context,void * argp)1323 static int ioctl_session_send_cmd(struct tc_ns_dev_file *dev_file,
1324 struct tc_ns_client_context *context, void *argp)
1325 {
1326 int ret;
1327
1328 ret = tc_ns_send_cmd(dev_file, context);
1329 if (ret != 0)
1330 tloge("send cmd failed ret is %d\n", ret);
1331 if (copy_to_user(argp, context, sizeof(*context)) != 0) {
1332 if (ret == 0)
1333 ret = -EFAULT;
1334 }
1335 return ret;
1336 }
1337
tc_client_session_ioctl(struct file * file,unsigned int cmd,unsigned long arg)1338 int tc_client_session_ioctl(struct file *file, unsigned int cmd,
1339 unsigned long arg)
1340 {
1341 int ret = -EINVAL;
1342 void *argp = (void __user *)(uintptr_t)arg;
1343 struct tc_ns_dev_file *dev_file = NULL;
1344 struct tc_ns_client_context context;
1345
1346 if (!argp || !file) {
1347 tloge("invalid params\n");
1348 return -EINVAL;
1349 }
1350
1351 dev_file = file->private_data;
1352 if (copy_from_user(&context, argp, sizeof(context)) != 0) {
1353 tloge("copy from user failed\n");
1354 return -EFAULT;
1355 }
1356
1357 context.returns.origin = TEEC_ORIGIN_COMMS;
1358 switch (cmd) {
1359 case TC_NS_CLIENT_IOCTL_SES_OPEN_REQ:
1360 ret = tc_ns_open_session(dev_file, &context);
1361 if (ret != 0)
1362 tloge("open session failed ret is %d\n", ret);
1363 if (copy_to_user(argp, &context, sizeof(context)) != 0 && ret == 0)
1364 ret = -EFAULT;
1365 break;
1366 case TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ:
1367 ret = tc_ns_close_session(dev_file, &context);
1368 break;
1369 case TC_NS_CLIENT_IOCTL_SEND_CMD_REQ:
1370 tee_trace_add_event(INVOKE_CMD_START, 0);
1371 ret = ioctl_session_send_cmd(dev_file, &context, argp);
1372 tee_trace_add_event(INVOKE_CMD_END, 0);
1373 break;
1374 default:
1375 tloge("invalid cmd:0x%x!\n", cmd);
1376 return ret;
1377 }
1378 /*
1379 * Don't leak ERESTARTSYS to user space.
1380 *
1381 * CloseSession is not reentrant, so convert to -EINTR.
1382 * In other case, restart_syscall().
1383 *
1384 * It is better to call it right after the error code
1385 * is generated (in tc_client_call), but kernel CAs are
1386 * still exist when these words are written. Setting TIF
1387 * flags for callers of those CAs is very hard to analysis.
1388 *
1389 * For kernel CA, when ERESTARTSYS is seen, loop in kernel
1390 * instead of notifying user.
1391 *
1392 * P.S. ret code in this function is in mixed naming space.
1393 * See the definition of ret. However, this function never
1394 * return its default value, so using -EXXX is safe.
1395 */
1396 if (ret == -ERESTARTSYS) {
1397 if (cmd == TC_NS_CLIENT_IOCTL_SES_CLOSE_REQ)
1398 ret = -EINTR;
1399 else
1400 return restart_syscall();
1401 }
1402 return ret;
1403 }
1404
cleanup_session(struct tc_ns_service * service)1405 static void cleanup_session(struct tc_ns_service *service)
1406 {
1407 struct tc_ns_session *session = NULL;
1408 struct tc_ns_session *session_tmp = NULL;
1409
1410 if (!service)
1411 return;
1412
1413 /* close unclosed session */
1414 if (list_empty(&service->session_list) == 0) {
1415 mutex_lock(&service->operation_lock);
1416 list_for_each_entry_safe(session, session_tmp, &service->session_list, head) {
1417 tlogd("clean up session %u\n", session->session_id);
1418 mutex_lock(&service->session_lock);
1419 list_del(&session->head);
1420 mutex_unlock(&service->session_lock);
1421 put_session_struct(session);
1422 }
1423 mutex_unlock(&service->operation_lock);
1424 }
1425 put_service_struct(service);
1426
1427 return;
1428 }
1429
free_all_session(void)1430 void free_all_session(void)
1431 {
1432 struct tc_ns_dev_file *dev_file = NULL;
1433 struct tc_ns_dev_file *dev_file_tmp = NULL;
1434 struct tc_ns_dev_list *dev_list = NULL;
1435 int i;
1436
1437 dev_list = get_dev_list();
1438 if (!dev_list) {
1439 tloge("cleanup session, dev list is null\n");
1440 return;
1441 }
1442 mutex_lock(&dev_list->dev_lock);
1443 list_for_each_entry_safe(dev_file, dev_file_tmp, &dev_list->dev_file_list, head) {
1444 mutex_lock(&dev_file->service_lock);
1445 for (i = 0; i < SERVICES_MAX_COUNT; i++) {
1446 if (dev_file->services[i] == NULL)
1447 continue;
1448 get_service_struct(dev_file->services[i]);
1449 /* avoid dead lock in close session */
1450 mutex_unlock(&dev_file->service_lock);
1451 cleanup_session(dev_file->services[i]);
1452 mutex_lock(&dev_file->service_lock);
1453 dev_file->services[i] = NULL;
1454 }
1455 mutex_unlock(&dev_file->service_lock);
1456 }
1457 mutex_unlock(&dev_list->dev_lock);
1458 return;
1459 }
1460