• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 #define _GNU_SOURCE
13 #include "drv_dispatch.h"
14 #include <stdint.h>
15 #include <inttypes.h>
16 #include <pthread.h>
17 #include <securec.h>
18 #include <ipclib.h>
19 #include <tee_log.h>
20 #include <ta_framework.h>
21 #include <drv.h>
22 #include <tee_drv_internal.h>
23 #include <tee_drv_errno.h>
24 #include <target_type.h>
25 #include <ta_lib_img_unpack.h>
26 #include "tee_driver_module.h"
27 #include "drv_thread.h"
28 #include "drv_fd_ops.h"
29 #include "drv_ipc_mgr.h"
30 #include "drv_auth.h"
31 #include "drv_dyn_conf_mgr.h"
32 #include "drvcall_dyn_conf_mgr.h"
33 #include "drv_process_mgr.h"
34 #include "task_mgr.h"
35 #include "base_drv_node.h"
36 #include <ipclib_hal.h>
37 #include <spawn_ext.h>
38 #include <unistd.h>
39 
get_drv_params(struct tee_drv_param * params,const struct drv_req_msg_t * msg,const struct src_msginfo * info)40 static int32_t get_drv_params(struct tee_drv_param *params, const struct drv_req_msg_t *msg,
41                               const struct src_msginfo *info)
42 {
43     spawn_uuid_t uuid;
44     int32_t ret;
45     if (msg == NULL || info == NULL) {
46         tloge("invalid parameters\n");
47         return -1;
48     }
49 
50     ret = getuuid(info->src_pid, &uuid);
51     if (ret != 0) {
52         tloge("get pid:%u uuid failed\n", info->src_pid);
53         return -1;
54     }
55 
56     ret = memcpy_s(&(params->uuid), sizeof(params->uuid), &uuid.uuid, sizeof(uuid.uuid));
57     if (ret != 0) {
58         tloge("copy pid:%u uuid:0x%x to params failed\n", info->src_pid, uuid.uuid.timeLow);
59         return -1;
60     }
61 
62     params->args = (uintptr_t)msg->args;
63     params->data = (uintptr_t)msg->data;
64     params->caller_pid = pid_to_taskid(info->src_tid, info->src_pid);
65 
66     return 0;
67 }
68 
get_drv_name(const struct tee_drv_param * params,char * drv_name,uint32_t len)69 static int32_t get_drv_name(const struct tee_drv_param *params, char *drv_name, uint32_t len)
70 {
71     char *indata = (char *)(uintptr_t)params->data;
72     uint64_t *args = (uint64_t *)(uintptr_t)params->args;
73     uint64_t name_len = args[DRV_NAME_LEN_INDEX];
74     uint64_t drv_name_offset = args[DRV_NAME_INDEX];
75 
76     if (indata == NULL) {
77         tloge("invalid input buffer\n");
78         return -1;
79     }
80 
81     if (name_len == 0 || name_len >= len) {
82         tloge("drv name len %"PRIx64" is invalid\n", name_len);
83         return -1;
84     }
85 
86     if (drv_name_offset != args[DRV_PARAM_LEN_INDEX] ||
87         (drv_name_offset > (SYSCAL_MSG_BUFFER_SIZE - sizeof(struct drv_req_msg_t))) ||
88         (drv_name_offset + name_len > (SYSCAL_MSG_BUFFER_SIZE - sizeof(struct drv_req_msg_t)))) {
89         tloge("drv name offset %"PRIx64" is invalid\n", args[DRV_NAME_INDEX]);
90         return -1;
91     }
92 
93     if (memcpy_s(drv_name, len, (indata + drv_name_offset), name_len) != EOK) {
94         tloge("copy drv name failed\n");
95         return -1;
96     }
97 
98     drv_name[name_len] = '\0';
99 
100     return 0;
101 }
102 
is_drv_call_invalid(const struct task_node * call_node,const char * drv_name,uint32_t len)103 static bool is_drv_call_invalid(const struct task_node *call_node, const char *drv_name, uint32_t len)
104 {
105     if (call_node->target_type != DRV_TARGET_TYPE)
106         return false;
107 
108     if (call_node->tlv.drv_conf == NULL) {
109         tloge("something wrong, drv conf is null\n");
110         return true;
111     }
112 
113     tlogd("this is drv:%s call other drv:%s\n", call_node->tlv.drv_conf->mani.service_name, drv_name);
114     if ((len == call_node->tlv.drv_conf->mani.service_name_size) &&
115         (strncmp(call_node->tlv.drv_conf->mani.service_name, drv_name, len + 1) == 0)) {
116         tloge("drv:%s call yourself not support\n", drv_name);
117         return true;
118     }
119 
120     return false;
121 }
122 
alloc_drvcall_node_internal_drv(const struct tee_uuid * uuid,uint32_t taskid)123 static struct task_node *alloc_drvcall_node_internal_drv(const struct tee_uuid *uuid, uint32_t taskid)
124 {
125     struct drvcall_conf_t *tlv = malloc(sizeof(struct drvcall_conf_t));
126     if (tlv == NULL) {
127         tloge("malloc tlv node failed\n");
128         return NULL;
129     }
130     (void)memset_s(tlv, sizeof(*tlv), 0, sizeof(*tlv));
131     (void)memcpy_s(&(tlv->uuid), sizeof(tlv->uuid), uuid, sizeof(*uuid));
132 
133     tlv->drvcall_perm_apply.base_perm = true;
134     struct task_node *node = alloc_and_init_ta_node(tlv);
135     if (node == NULL) {
136         free(tlv);
137         tloge("create drvcall node fail\n ");
138         return NULL;
139     }
140 
141     node->pid = taskid_to_pid(taskid);
142     if (receive_task_conf(node) != 0) {
143         tloge("receive task conf fail\n");
144         free(tlv);
145         free_task_node(node);
146         return NULL;
147     }
148     free(tlv);
149 
150     return node;
151 }
152 
get_valid_drvcall_node(const struct tee_uuid * uuid,uint32_t taskid,const char * drv_name,uint32_t len)153 static struct task_node *get_valid_drvcall_node(const struct tee_uuid *uuid,
154     uint32_t taskid, const char *drv_name, uint32_t len)
155 {
156     bool base_drv_flag = get_base_drv_flag(drv_name, len);
157 
158     struct task_node *call_node = get_node_by_uuid_with_lock(uuid, taskid);
159     if (call_node == NULL) {
160         if (base_drv_flag) {
161             call_node = alloc_drvcall_node_internal_drv(uuid, taskid);
162         } else {
163             tloge("cannot get caller node:0x%x taskid is 0x%x\n", uuid->timeLow, taskid);
164             return NULL;
165         }
166     }
167 
168     if (is_drv_call_invalid(call_node, drv_name, len))
169         goto put_drvcall;
170     /* first check whether caller has the right to access this drv */
171     if (!base_drv_flag) {
172         if (!caller_open_auth_check(call_node, drv_name, len)) {
173             tloge("caller:0x%x cannot access %s\n", uuid->timeLow, drv_name);
174             goto put_drvcall;
175         }
176     }
177 
178     int32_t ret = get_fd_count(call_node);
179     if (ret != 0) {
180         tloge("caller:0x%x get fd count fail\n", uuid->timeLow);
181         goto put_drvcall;
182     }
183 
184     return call_node;
185 
186 put_drvcall:
187     put_node_with_lock(call_node, 1);
188     return NULL;
189 }
190 
191 #define ELF_APPEND_LEN 4 /* ".elf" */
unlink_drv_elf(const char * drv_name)192 static void unlink_drv_elf(const char *drv_name)
193 {
194     char drv_elf[DRV_NAME_MAX_LEN + ELF_APPEND_LEN] = { 0 };
195 
196     int32_t ret = snprintf_s(drv_elf, sizeof(drv_elf), (sizeof(drv_elf) - 1), "%s%s",
197         drv_name, ".elf");
198     if (ret < 0) {
199         tloge("set unlink drv:%s elf fail\n", drv_name);
200         return;
201     }
202 
203     uint32_t ipc_ret = ipc_msg_snd(TEE_UNLINK_DYNAMIC_DRV, GLOBAL_HANDLE, drv_elf, sizeof(drv_elf));
204     if (ipc_ret != 0)
205         tloge("send unlink drv:%s msg fail:0x%x", drv_name, ipc_ret);
206 
207     tlogd("unlink drv:%s succ\n", drv_elf);
208 }
209 
get_valid_drv_node(const struct tee_uuid * caller_uuid,const char * drv_name,uint32_t len)210 static struct task_node *get_valid_drv_node(const struct tee_uuid *caller_uuid, const char *drv_name, uint32_t len)
211 {
212     struct task_node *dnode = get_drv_node_by_name_with_lock(drv_name, len);
213     if (dnode == NULL) {
214         tloge("cannot find drv:%s\n", drv_name);
215         return NULL;
216     }
217 
218     if (!drv_mac_open_auth_check(dnode->tlv.drv_conf, caller_uuid)) {
219         tloge("drv:%s mac check fail 0x%x", drv_name, caller_uuid->timeLow);
220         goto put_drv;
221     }
222 
223     int32_t ret = check_drv_node_state(dnode);
224     if (ret == DRV_NEED_SPAWN) {
225         /* spawn process */
226         tlogd("SPAWN drv:%s begin\n", drv_name);
227         ret = spawn_driver_handle(dnode);
228         if (ret != 0) {
229             tloge("spawn drv:%s fail\n", drv_name);
230             broadcast_drv_state(dnode, false);
231         } else {
232             tlogd("spawn drv:%s succ and broadcast\n", drv_name);
233             broadcast_drv_state(dnode, true);
234             unlink_drv_elf(drv_name);
235             return dnode;
236         }
237     } else if (ret == DRV_SUCC) {
238         tlogd("drv:%s has spawn succ\n", drv_name);
239         return dnode;
240     }
241 
242     tloge("cannot find drv:%s spawn node\n", drv_name);
243 
244 put_drv:
245     put_node_with_lock(dnode, 1);
246     return NULL;
247 }
248 
driver_open_func(const struct tee_drv_param * params)249 static int64_t driver_open_func(const struct tee_drv_param *params)
250 {
251     char drv_name[DRV_NAME_MAX_LEN] = { 0 };
252     if (get_drv_name(params, drv_name, sizeof(drv_name)) != 0)
253         return -1;
254 
255     struct task_node *call_node = get_valid_drvcall_node(&params->uuid, params->caller_pid, drv_name, strlen(drv_name));
256     if (call_node == NULL)
257         return -1;
258 
259     struct fd_node *data = alloc_and_init_fd_node();
260     if (data == NULL)
261         goto put_drvcall;
262 
263     struct task_node *dnode = get_valid_drv_node(&params->uuid, drv_name, strlen(drv_name));
264     if (dnode == NULL)
265         goto free_fd;
266 
267     /*
268      * get drvcall cmd permission, and send to driver process
269      * it will be used in ioctl function to check whether drvcaller has special cmd permission
270      */
271     uint64_t caller_perm;
272     bool base_drv_flag = get_base_drv_flag(drv_name, strlen(drv_name));
273     if (base_drv_flag) {
274         caller_perm = 0;
275     } else {
276         int32_t ret = get_drvcaller_cmd_perm(call_node, dnode, &caller_perm);
277         if (ret != 0) {
278             tloge("get caller:0x%x drv:%s cmd perm fail\n", params->uuid.timeLow, drv_name);
279             goto put_drv;
280         }
281     }
282     int64_t fd = drv_open_handle(params, dnode, caller_perm);
283     if (fd <= 0) {
284         tloge("drv:%s open fd fail:0x%llx\n", drv_name, fd);
285         goto put_drv;
286     }
287 
288     data->fd = fd;
289     data->drv = dnode;
290 
291     if (add_fd_to_drvcall_node(data, call_node) != 0) {
292         tloge("add fd fail\n");
293         goto close_fd;
294     }
295 
296     tlogd("caller:0x%x open drv:%s fd:0x%llx end\n", params->uuid.timeLow, drv_name, fd);
297 
298     return fd;
299 
300 close_fd:
301     if (call_drv_close(call_node->pid, &params->uuid, fd, dnode->drv_task.channel) != 0)
302         tloge("call drv:%s close fd:0x%llx fail\n", drv_name, fd);
303 
304 put_drv:
305     put_node_with_lock(dnode, 1);
306 
307 free_fd:
308     free(data);
309 
310 put_drvcall:
311     put_fd_count(call_node);
312     put_node_with_lock(call_node, 1);
313     return -1;
314 }
315 
driver_close_func_ops(struct task_node * call_node,int64_t fd,struct fd_node ** data)316 static int64_t driver_close_func_ops(struct task_node *call_node, int64_t fd, struct fd_node **data)
317 {
318     struct task_node *dnode = (*data)->drv;
319     if (dnode == NULL) {
320         tloge("something wrong, task:0x%x uuid:0x%x fd:0x%llx data has no drv\n",
321             call_node->pid, call_node->tlv.uuid.timeLow, fd);
322         del_fd_to_drvcall_node(data, call_node);
323         return -1;
324     }
325 
326     /*
327      * must del fd in drvcall node before call drv_close
328      * otherwise will cause fd data cannot close in this case:
329      * two session of the same TA call the same drv,
330      * session 0 in cpux close the fd1 and session 1 in cpuy open new fd
331      * when drv free fd1 first, it may alloc fd1 to session 1 (session 0 close fd1, and session 1 open fd1 again)
332      * if not del fd data of this task in drvmgr, it may cannot find valid fd1 (close_flag = false)
333      * when session 1 close fd1 opened before since this task in drvmgr has two fd1,
334      * one opened by session 0 has set close_flag, another opened by session 1 has not set close_flag,
335      * session 1 close fd1 may find the session 0 opened since it just compare the fd1 value
336      */
337     del_fd_to_drvcall_node(data, call_node);
338 
339     int64_t ret = call_drv_close(call_node->pid, &call_node->tlv.uuid, fd, dnode->drv_task.channel);
340     if (ret != 0)
341         tloge("call drv close fd:0x%llx for task:0x%x fail ret:0x%x\n", fd, call_node->pid, ret);
342 
343     /* pair with dnode ref_cnt add one in open */
344     put_node_with_lock(dnode, 1);
345 
346     return ret;
347 }
348 
driver_close_func(int64_t fd,const struct tee_drv_param * params)349 static int64_t driver_close_func(int64_t fd, const struct tee_drv_param *params)
350 {
351     int64_t ret = DRV_GENERAL_ERR;
352 
353     tlogd("call drv fd:0x%llx close begin\n", fd);
354 
355     struct task_node *call_node = get_node_by_uuid_with_lock(&params->uuid, params->caller_pid);
356     if (call_node == NULL) {
357         tloge("cannot get call node pid:0x%x uuid:0x%x for fd:0x%llx\n",
358             params->caller_pid, params->uuid.timeLow, fd);
359         return ret;
360     }
361 
362     struct fd_node *data = close_get_fd_node_with_lock(call_node, fd);
363     if (data == NULL) {
364         /*
365          * two case:
366          * 1. the caller has not open this fd
367          * 2. this fd has been closed in exception handle
368          */
369         tloge("task:0x%x uuid:0x%x cannot find fd:0x%llx\n",
370             params->caller_pid, params->uuid.timeLow, fd);
371         put_node_with_lock(call_node, 1);
372         return DRV_GENERAL_ERR;
373     }
374 
375     ret = driver_close_func_ops(call_node, fd, &data);
376 
377     /*
378      * one for get_drvcall_by_uuid_with_lock
379      * one for pair with open
380      */
381     put_node_with_lock(call_node, DRVCALL_DEC_CNT_INCLUDE_REGISTER_ONE);
382 
383     tlogd("drv fd:0x%llx close ret:0x%llx\n", fd, ret);
384 
385     /*
386      * In this case must dec channel ref_cnt in lib
387      * because this fd can be find in drvmgr
388      */
389     if (ret != DRV_SUCCESS) {
390         tloge("find fd:0x%llx but close fail\n", fd);
391         return DRV_CLOSE_FD_FAIL;
392     }
393 
394     return ret;
395 }
396 
driver_general_handle(const struct tee_drv_param * params,int64_t * ret_val)397 static int32_t driver_general_handle(const struct tee_drv_param *params, int64_t *ret_val)
398 {
399     uint64_t *args = (uint64_t *)(uintptr_t)params->args;
400     if (args == NULL) {
401         tloge("args is invalid\n");
402         return -1;
403     }
404 
405     uint64_t drv_cmd = args[DRV_FRAM_CMD_INDEX];
406     int64_t ret;
407 
408     if (drv_cmd == CALL_DRV_OPEN) {
409         ret = driver_open_func(params);
410     } else if (drv_cmd == CALL_DRV_CLOSE) {
411         ret = driver_close_func(args[DRV_CLOSE_FD_INDEX], params);
412     } else {
413         tloge("drv cmd:%" PRIx64 " not support\n", drv_cmd);
414         return -1;
415     }
416 
417     *ret_val = ret;
418 
419     return 0;
420 }
421 
422 #define EXIT_PID_INDEX 0
driver_exception_handle(const struct tee_drv_param * params,int64_t * ret_val)423 static int32_t driver_exception_handle(const struct tee_drv_param *params, int64_t *ret_val)
424 {
425     uint32_t pid = taskid_to_pid(params->caller_pid);
426     if (pid != GLOBAL_HANDLE) {
427         tloge("task:0x%x not gtask, cannot call exception handle\n", pid);
428         return -1;
429     }
430 
431     uint64_t *args = (uint64_t *)(uintptr_t)params->args;
432     if (args == NULL) {
433         tloge("args is invalid\n");
434         return -1;
435     }
436 
437     uint64_t exit_pid = args[EXIT_PID_INDEX];
438     if (exit_pid > UINT32_MAX) {
439         tloge("invalid exit_pid\n");
440         return -1;
441     }
442 
443     tloge("receive drv crash taskid:0x%x\n", (uint32_t)exit_pid);
444     if (find_drv_node_by_taskid(exit_pid) != NULL)
445         tee_abort("drv taskid:0x%x abort\n", (uint32_t)exit_pid);
446 
447     *ret_val = 0;
448     return 0;
449 }
450 
451 /*
452  * register or unregister maybe called by permission service
453  * if the permission service is supported
454  */
check_caller_from_legal_service(const struct tee_drv_param * params)455 static bool check_caller_from_legal_service(const struct tee_drv_param *params)
456 {
457     uint32_t pid = taskid_to_pid(params->caller_pid);
458     if (pid == GLOBAL_HANDLE)
459         return true;
460 
461 #if defined(TEE_SUPPORT_PERM_64BIT) || defined(TEE_SUPPORT_PERM_32BIT)
462     struct tee_uuid perm_srv = TEE_SERVICE_PERM;
463     if (memcmp(&params->uuid, &perm_srv, sizeof(perm_srv)) == 0)
464         return true;
465 #endif
466 
467     return false;
468 }
469 
470 #define DRV_CONF_LEN_INDEX 1
471 #define DRV_CONF_OFF_INDEX 0
472 
drv_conf_register_handle(const struct tee_drv_param * params,int64_t * ret_val)473 static int32_t drv_conf_register_handle(const struct tee_drv_param *params, int64_t *ret_val)
474 {
475     uint64_t *args = (uint64_t *)(uintptr_t)(params->args);
476     char *indata = (char *)(uintptr_t)params->data;
477     if (args == NULL || indata == NULL) {
478         tloge("drv conf register handle invalied args and indata params\n");
479         return -1;
480     }
481 
482     uint64_t len = args[DRV_CONF_LEN_INDEX];
483 
484     if (len != sizeof(struct drv_tlv) || args[DRV_CONF_OFF_INDEX] != 0) {
485         tloge("invalied params\n");
486         return -1;
487     }
488 
489     if (!check_caller_from_legal_service(params)) {
490         tloge("drv conf can only register from legal service\n");
491         return -1;
492     }
493 
494     struct drv_tlv tlv;
495     if (memcpy_s(&tlv, sizeof(tlv), indata, len) != 0) {
496         tloge("memcpy for tlv failed\n");
497         return -1;
498     }
499 
500     struct task_node *node = alloc_and_init_drv_node(&tlv);
501     if (node == NULL) {
502         tloge("alloc drv node fail\n");
503         return -1;
504     }
505 
506     if (receive_task_conf(node) != 0) {
507         tloge("receive drv task fail\n");
508         free_task_node(node);
509         return -1;
510     }
511 
512     if (check_hardware_type(node, HARDWARE_ENGINE_CRYPTO))
513         free_task_node(node);
514 
515     *ret_val = 0;
516     return 0;
517 }
518 
drv_conf_unregister_handle(const struct tee_drv_param * params,int64_t * ret_val)519 static int32_t drv_conf_unregister_handle(const struct tee_drv_param *params, int64_t *ret_val)
520 {
521     uint64_t *args = (uint64_t *)(uintptr_t)(params->args);
522     char *indata = (char *)(uintptr_t)params->data;
523     if (args == NULL || indata == NULL) {
524         tloge("drv conf unregister handle invalied args and indata params\n");
525         return -1;
526     }
527 
528     uint64_t len = args[DRV_CONF_LEN_INDEX];
529     char service_name[DRV_NAME_MAX_LEN + 1] = { 0 };
530 
531     if (len == 0 || len >= DRV_NAME_MAX_LEN || args[DRV_CONF_OFF_INDEX] != 0) {
532         tloge("invalied params\n");
533         return -1;
534     }
535 
536     if (!check_caller_from_legal_service(params)) {
537         tloge("drv conf can only unregist from legal service\n");
538         return -1;
539     }
540 
541     if (memcpy_s(service_name, DRV_NAME_MAX_LEN, indata, (size_t)len) != 0) {
542         tloge("memcpy service_name failed\n");
543         return -1;
544     }
545 
546     if (free_drv_conf_by_service_name(service_name, len) != 0) {
547         tloge("free drv conf failed\n");
548         return -1;
549     }
550 
551     *ret_val = 0;
552     return 0;
553 }
554 
555 #define DRVCALL_CONF_LEN_INDEX 1
556 #define DRVCALL_CONF_OFF_INDEX 0
557 #define DRVCALL_TASKID_INDEX 2
558 
drvcall_conf_register_handle(const struct tee_drv_param * params,int64_t * ret_val)559 static int32_t drvcall_conf_register_handle(const struct tee_drv_param *params, int64_t *ret_val)
560 {
561     uint64_t *args = (uint64_t *)(uintptr_t)(params->args);
562     char *indata = (char *)(uintptr_t)params->data;
563     if (args == NULL || indata == NULL) {
564         tloge("drvcall conf register handle invalied args and indata params\n");
565         return -1;
566     }
567 
568     uint64_t len = args[DRVCALL_CONF_LEN_INDEX];
569     if (len != sizeof(struct drvcall_conf_t) || args[DRVCALL_CONF_OFF_INDEX] != 0) {
570         tloge("drvcall conf register handle invalied params\n");
571         return -1;
572     }
573 
574     if (!check_caller_from_legal_service(params)) {
575         tloge("drvcall conf can only register from legal service\n");
576         return -1;
577     }
578 
579     struct drvcall_conf_t drvcall;
580     if (memcpy_s(&drvcall, sizeof(drvcall), indata, len) != 0) {
581         tloge("memcpy for drvcall failed\n");
582         return -1;
583     }
584 
585     drvcall.drvcall_perm_apply.base_perm = false;
586 
587     struct task_node *node = alloc_and_init_ta_node(&drvcall);
588     if (node == NULL) {
589         tloge("create drvcall node fail\n ");
590         return -1;
591     }
592 
593     if (receive_task_conf(node) != 0) {
594         tloge("receive task conf fail\n");
595         free_task_node(node);
596         return -1;
597     }
598 
599     *ret_val = 0;
600     return 0;
601 }
602 
drvcall_conf_unregister_handle(const struct tee_drv_param * params,cref_t reply_hdl,struct drv_reply_msg_t * reply,int64_t * ret_val)603 static int32_t drvcall_conf_unregister_handle(const struct tee_drv_param *params,
604     cref_t reply_hdl, struct drv_reply_msg_t *reply, int64_t *ret_val)
605 {
606     uint64_t *args = (uint64_t *)(uintptr_t)(params->args);
607     char *indata = (char *)(uintptr_t)params->data;
608     if (args == NULL || indata == NULL) {
609         tloge("drvcall conf unregister handle invalied args and indata params\n");
610         return -1;
611     }
612 
613     uint64_t len = args[DRVCALL_CONF_LEN_INDEX];
614     struct tee_uuid uuid;
615 
616     if (len != sizeof(uuid) || args[DRVCALL_CONF_OFF_INDEX] != 0) {
617         tloge("invalied params\n");
618         return -1;
619     }
620 
621     if (!check_caller_from_legal_service(params)) {
622         tloge("drvcall conf can only unregist from legal service\n");
623         return -1;
624     }
625 
626     if (memcpy_s(&uuid, sizeof(uuid), indata, (size_t)len) != 0) {
627         tloge("memcpy uuid failed\n");
628         return -1;
629     }
630 
631     struct task_node *node = get_ta_node_and_set_exit(&uuid);
632 
633     reply->header.reply.ret_val = 0;
634     int32_t ret = ipc_msg_reply(reply_hdl, reply, sizeof(*reply));
635     if (ret != 0)
636         tloge("exception reply fail:0x%x\n", ret);
637 
638     if (node != NULL) {
639         uint32_t close_fd = exception_close_handle(node);
640 
641         /*
642          * close_fd for those fd that not close normally
643          * 2: one for get_drvcall_and_set_exit, another one for register drvcall
644          */
645         put_node_with_lock(node, (close_fd + DRVCALL_DEC_CNT_INCLUDE_REGISTER_ONE));
646     } else {
647         /* maybe the exit process has not register */
648         tlogd("cannot find taskid:0x%x drvcall\n", taskid);
649     }
650 
651     *ret_val = 0;
652     return 0;
653 }
654 
655 #ifdef TEE_SUPPORT_DYN_CONF_DEBUG
drvcall_conf_dump_handle(const struct tee_drv_param * params,int64_t * ret_val)656 static int32_t drvcall_conf_dump_handle(const struct tee_drv_param *params, int64_t *ret_val)
657 {
658     (void)params;
659     *ret_val = 0;
660 
661     dump_task_node();
662 
663     return 0;
664 }
665 #endif
666 
driver_syscall_dispatch(int32_t swi_id,const struct tee_drv_param * params,cref_t reply_hdl,struct drv_reply_msg_t * reply,int64_t * ret_val)667 static int32_t driver_syscall_dispatch(int32_t swi_id, const struct tee_drv_param *params,
668     cref_t reply_hdl, struct drv_reply_msg_t *reply, int64_t *ret_val)
669 {
670     int32_t ret = -1;
671 
672     switch (swi_id) {
673     case DRV_GENERAL_CMD_ID:
674         ret = driver_general_handle(params, ret_val);
675         break;
676     case DRV_EXCEPTION_CMD_ID:
677         ret = driver_exception_handle(params, ret_val);
678         break;
679     case REGISTER_DRV_CONF:
680         ret = drv_conf_register_handle(params, ret_val);
681         break;
682     case UNREGISTER_DRV_CONF:
683         ret = drv_conf_unregister_handle(params, ret_val);
684         break;
685     case REGISTER_DRVCALL_CONF:
686         ret = drvcall_conf_register_handle(params, ret_val);
687         break;
688     case UNREGISTER_DRVCALL_CONF:
689         ret = drvcall_conf_unregister_handle(params, reply_hdl, reply, ret_val);
690         break;
691 #ifdef TEE_SUPPORT_DYN_CONF_DEBUG
692     case DUMP_DRVCALL_CONF:
693         ret = drvcall_conf_dump_handle(params, ret_val);
694         break;
695 #endif
696     default:
697         tloge("swi_id:0x%x cannot handle\n", swi_id);
698     }
699 
700     return ret;
701 }
702 
driver_open_reply_error_callback(int64_t fd,const struct tee_drv_param * params)703 static void driver_open_reply_error_callback(int64_t fd, const struct tee_drv_param *params)
704 {
705     struct task_node *call_node = NULL;
706     struct fd_node *data = NULL;
707 
708     int32_t ret = get_drvcall_and_fd_node(fd, params, &call_node, &data);
709     if (ret != 0)
710         return;
711 
712     tloge("open callback find fd:0x%llx for taskid:0x%x uuid:0x%x\n",
713         fd, params->caller_pid, params->uuid.timeLow);
714 
715     /* no care whether succ or fail */
716     (void)driver_close_func_ops(call_node, fd, &data);
717 
718     /*
719      * one for get_drvcall_and_fd_node
720      * one pair with register drvcall
721      */
722     put_node_with_lock(call_node, DRVCALL_DEC_CNT_INCLUDE_REGISTER_ONE);
723 }
724 
driver_reply_error_handle(int32_t swi_id,const struct tee_drv_param * params,int64_t ret_val)725 static void driver_reply_error_handle(int32_t swi_id, const struct tee_drv_param *params, int64_t ret_val)
726 {
727     uint64_t *args = (uint64_t *)(uintptr_t)params->args;
728     if (args == NULL) {
729         tloge("args is invalid\n");
730         return;
731     }
732 
733     if (!((swi_id == DRV_GENERAL_CMD_ID) && (args[DRV_FRAM_CMD_INDEX] == CALL_DRV_OPEN)))
734         return;
735 
736     if (ret_val <= 0)
737         return;
738 
739     tloge("drv open reply failed, call drv close fd:%"PRIx64"\n", ret_val);
740     driver_open_reply_error_callback(ret_val, params);
741 }
742 
driver_handle_message(const struct drv_req_msg_t * msg,const struct src_msginfo * info,struct drv_reply_msg_t * rmsg,const cref_t * msg_hdl)743 static int32_t driver_handle_message(const struct drv_req_msg_t *msg, const struct src_msginfo *info,
744                                      struct drv_reply_msg_t *rmsg, const cref_t *msg_hdl)
745 {
746     int64_t ret_val = -1;
747     int32_t ret;
748     struct tee_drv_param params = { 0 };
749     int32_t swi_id = msg->header.send.msg_id;
750 
751     ret = get_drv_params(&params, msg, info);
752     if (ret != 0) {
753         tloge("get driver parameters failed\n");
754         return -1;
755     }
756 
757     tid_t tid = gettid();
758     if (tid < 0) {
759         tloge("failed to get tid\n");
760         return -1;
761     }
762 
763     update_callerpid_by_tid(tid, params.caller_pid);
764     ret = driver_syscall_dispatch(swi_id, &params, *msg_hdl, rmsg, &ret_val);
765     update_callerpid_by_tid(tid, INVALID_CALLER_PID);
766     if (ret != 0)
767         tloge("handle swi 0x%x failed\n", swi_id);
768 
769     /*
770      * in exception_close_handle, will send reply msg when handle succ,
771      * but not send reply msg when handle fail
772      */
773     if ((swi_id != UNREGISTER_DRVCALL_CONF) || (swi_id == UNREGISTER_DRVCALL_CONF && ret != 0)) {
774         rmsg->header.reply.ret_val = (ret == 0) ? ret_val : (int64_t)ret;
775         ret = ipc_msg_reply(*msg_hdl, rmsg, sizeof(struct drv_reply_msg_t));
776         if (ret != 0) {
777             tloge("msg reply for 0x%x failed\n", swi_id);
778             /*
779              * should clear system resource information alloced by this cmd when reply failed,
780              * otherwise it will cause memory leak
781              */
782             driver_reply_error_handle(swi_id, &params, ret_val);
783         }
784     }
785 
786     return ret;
787 }
788 
driver_dispatch(void * msg,cref_t * p_msg_hdl,struct src_msginfo * info)789 intptr_t driver_dispatch(void *msg, cref_t *p_msg_hdl, struct src_msginfo *info)
790 {
791     int32_t ret;
792     struct drv_reply_msg_t reply_raw_buf;
793 
794     if ((p_msg_hdl == NULL) || (info == NULL) || (msg == NULL)) {
795         tloge("invalid dispatch param\n");
796         return -1;
797     }
798 
799     (void)memset_s(&reply_raw_buf, sizeof(reply_raw_buf), 0, sizeof(reply_raw_buf));
800 
801     ret = driver_handle_message((struct drv_req_msg_t *)msg, info,
802         &reply_raw_buf, p_msg_hdl);
803     if (ret != 0)
804         tloge("driver handle message failed\n");
805 
806     return ret;
807 }
808