• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&params, 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(&params);
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(&params);
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(&params);
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