TEE_Result TA_EXPORT TA_OpenSessionEntryPoint(uint32_t paramTypes, TEE_Param params[4], void **sessionContext) { TEE_Result tee_rv = TEE_SUCCESS; OT_LOG(LOG_INFO, "Calling the Open session entry point"); tee_rv = handle_params(paramTypes, params); if (tee_rv != TEE_SUCCESS) return tee_rv; if (storage_test(2)) return TEE_ERROR_GENERIC; if (crypto_test(2)) return TEE_ERROR_GENERIC; if (*sessionContext != NULL) { OT_LOG(LOG_ERR, "Session context should be NULL"); return TEE_ERROR_BAD_PARAMETERS; } *sessionContext = TEE_Malloc(SIZE_OF_VEC(out_vector), 0); if (*sessionContext == NULL) { OT_LOG(LOG_ERR, "Can not malloc space for session context"); return TEE_ERROR_OUT_OF_MEMORY; } TEE_MemMove(*sessionContext, out_vector, SIZE_OF_VEC(out_vector)); return tee_rv; }
TEE_Result TA_EXPORT TA_CreateEntryPoint(void) { TEE_Result ret; uint64_t initial_value = 0; TEE_ObjectHandle counter; OT_LOG(LOG_ERR, "Calling the create entry point"); ret = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, &object_id, sizeof(object_id), TEE_DATA_FLAG_ACCESS_READ | TEE_DATA_FLAG_ACCESS_WRITE, &counter); if (ret == TEE_ERROR_ITEM_NOT_FOUND) { OT_LOG(LOG_DEBUG, "TEE_OpenPersistentObject failed, creating persistent object"); ret = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE, &object_id, sizeof(object_id), TEE_DATA_FLAG_ACCESS_READ | TEE_DATA_FLAG_ACCESS_WRITE, NULL, &initial_value, sizeof(initial_value), &counter); if (ret != TEE_SUCCESS) OT_LOG(LOG_ERR, "TEE_CreatePersistentObject failed: 0x%x", ret); else OT_LOG(LOG_DEBUG, "TEE_CreatePersistentObject succesful"); } TEE_CloseObject(counter); return ret; }
TEE_Result TA_EXPORT TA_InvokeCommandEntryPoint(void *sessionContext, uint32_t commandID, uint32_t paramTypes, TEE_Param params[4]) { int i; uint8_t *mem_data[3]; for (i = 0; i < 3; i++) mem_data[i] = (uint8_t *)(params[1+i].memref.buffer); sessionContext = sessionContext; commandID = commandID; paramTypes = paramTypes; if (commandID == 0) { OT_LOG(LOG_INFO, "Calling the Invoke command entry point"); } else if (commandID == 1) { if (params[1].memref.buffer == NULL) { OT_LOG(LOG_INFO, "NULL ???????????????"); return TEEC_ERROR_BAD_PARAMETERS; } for (i = 0; i < 20; i++) { /* return some data to the user */ mem_data[0][i] |= 1; mem_data[1][i] |= 4; mem_data[2][i] |= 8; } } return TEE_SUCCESS; }
static int wind_fd_next_start(int fd) { /* TODO: This function only emtying socket and due that message can be lost!! * * Use IOCTL call to find out data in socket, then peek and find next starting point */ static const int BUF_LEN = 256; char tmp[BUF_LEN]; int read_bytes; while (1) { read_bytes = read(fd, &tmp, BUF_LEN); if (read_bytes == -1) { if (errno == EINTR) continue; OT_LOG(LOG_ERR, "read error"); return -1; } else if (read_bytes == 0) { OT_LOG(LOG_ERR, "read error"); errno = EPIPE; return -1; } if (read_bytes == BUF_LEN) continue; else break; } return 1; /* This function should only call in com_recv_msg function */ }
TEE_Result TA_EXPORT TA_InvokeCommandEntryPoint(void *sessionContext, uint32_t commandID, uint32_t paramTypes, TEE_Param params[4]) { TEEC_Result ret = TEEC_SUCCESS; sessionContext = sessionContext; OT_LOG(LOG_DEBUG, "Calling the Invoke command entry point"); switch (commandID) { case CMD_GET_CTR: OT_LOG(LOG_DEBUG, "Command: GetCounter"); /* Check parameter type */ if (TEE_PARAM_TYPE_GET(paramTypes, 0) != TEE_PARAM_TYPE_MEMREF_INOUT) { OT_LOG(LOG_ERR, "Expected buffer input type as index 0 parameter"); ret = TEE_ERROR_BAD_PARAMETERS; goto end; } ret = get_counter_value((uint64_t *)(params[0].memref.buffer)); break; default: OT_LOG(LOG_ERR, "Unknown command"); break; } end: return ret; }
static int read_iov_element(int fd, struct iovec *iov, int *temp_fd, int *temp_fd_count) { int read_bytes = 0; while (1) { if (temp_fd) read_bytes = recv_fd(fd, temp_fd, temp_fd_count, iov, 1); else read_bytes = readv(fd, iov, 1); if (read_bytes == -1) { if (errno == EINTR) continue; OT_LOG(LOG_ERR, "read error"); return -1; } else if (read_bytes == 0) { OT_LOG(LOG_ERR, "read error"); errno = EPIPE; return -1; } break; } return read_bytes; }
TEE_Result TA_EXPORT TA_OpenSessionEntryPoint(uint32_t paramTypes, TEE_Param params[4], void **sessionContext) { int i; paramTypes = paramTypes; sessionContext = sessionContext; uint8_t *mem_data = (uint8_t *)(params[1].memref.buffer); OT_LOG(LOG_INFO, "Calling the Open session entry point"); OT_LOG(LOG_INFO, "param value is %d", params[0].value.a); OT_LOG(LOG_INFO, "param mem data size is %zu", params[1].memref.size); if (params[1].memref.buffer == NULL) OT_LOG(LOG_INFO, "NULL ???????????????"); mem_data[26] = 0; OT_LOG(LOG_INFO, "Mem value : %s", (char *)mem_data); for (i = 0; i < 20; i++) { /* return some data to the user */ mem_data[i] = 'y'; } return TEE_SUCCESS; }
TEE_Result TA_EXPORT TA_InvokeCommandEntryPoint(void *sessionContext, uint32_t commandID, uint32_t paramTypes, TEE_Param params[4]) { TEE_Result tee_rv = TEE_SUCCESS; /* Check session context */ if (TEE_MemCompare(sessionContext, out_vector, SIZE_OF_VEC(out_vector))) { OT_LOG(LOG_ERR, "Not a correct session context"); return TEE_ERROR_GENERIC; } if (!(commandID == INVOKE_CMD_ID_1 || commandID == INVOKE_CMD_ID_2)) { OT_LOG(LOG_ERR, "Not a valid command ID"); return TEE_ERROR_BAD_PARAMETERS; } tee_rv = handle_params(paramTypes, params); if (tee_rv != TEE_SUCCESS) return tee_rv; if (storage_test(2)) return TEE_ERROR_GENERIC; if (crypto_test(2)) return TEE_ERROR_GENERIC; return TEE_SUCCESS; }
static int wrap_epoll_ctl(int fd, struct epoll_event *event, int op) { if (epoll_ctl(epollfd, op, fd, event)) { OT_LOG(LOG_ERR, "Failed on epoll_ctl operation: 0x%x: %s", op, strerror(errno)); return -1; } return 0; }
void TA_EXPORT TA_CloseSessionEntryPoint(void *sessionContext) { OT_LOG(LOG_INFO, "Calling the Close session entry point"); if (storage_test(2)) TEE_Panic(TEE_ERROR_GENERIC); if (crypto_test(2)) TEE_Panic(TEE_ERROR_GENERIC); /* Check session context */ if (TEE_MemCompare(sessionContext, out_vector, SIZE_OF_VEC(out_vector))) { OT_LOG(LOG_ERR, "Not a correct session context"); TEE_Panic(TEE_ERROR_GENERIC); } TEE_Free(sessionContext); }
void TA_EXPORT TA_DestroyEntryPoint(void) { OT_LOG(LOG_INFO, "Calling the Destroy entry point"); if (storage_test(2)) TEE_Panic(TEE_ERROR_GENERIC); if (crypto_test(2)) TEE_Panic(TEE_ERROR_GENERIC); }
TEE_Result TA_EXPORT TA_CreateEntryPoint(void) { OT_LOG(LOG_ERR, "Calling the create entry point"); /* Run one round of testcases */ ta_storage_test(1); return TEE_SUCCESS; }
int init_epoll() { epollfd = epoll_create(10); if (epollfd < 0) { OT_LOG(LOG_ERR, "Failed to create epoll fd: %s", strerror(errno)); return -1; } return 0; }
static void send_err_msg_to_manager(int man_fd, struct com_msg_ta_created *msg) { /* No special error message. PID -1 is signaling error */ msg->pid = -1; /* TA not created */ if (com_send_msg(man_fd, msg, sizeof(struct com_msg_ta_created), NULL, 0) != sizeof(struct com_msg_ta_created)) { OT_LOG(LOG_ERR, "Failed report fail"); } }
int com_send_msg(int sockfd, void *msg, int msg_len, int *shareable_fd, int shareable_fd_count) { struct iovec iov[ELEMENTS_IN_MESSAGE] = { {0} }; int bytes_write; struct com_transport_info com_trans_info = {0}; if (!msg) { OT_LOG(LOG_ERR, "message null"); return -1; } /* Fill and calculate transport information */ com_trans_info.start = COM_MSG_START; com_trans_info.data_len = msg_len; com_trans_info.checksum = crc32(0, msg, msg_len); iov[0].iov_base = &com_trans_info; iov[0].iov_len = sizeof(struct com_transport_info); iov[1].iov_base = msg; iov[1].iov_len = msg_len; /* Send message */ while (1) { bytes_write = send_fd(sockfd, shareable_fd, shareable_fd_count, iov, ELEMENTS_IN_MESSAGE); if (bytes_write == -1) { if (errno == EINTR) continue; OT_LOG(LOG_ERR, "send error: %s", strerror(errno)); return -1; } break; } return bytes_write - sizeof(struct com_transport_info); }
TEE_Result TA_EXPORT TA_OpenSessionEntryPoint(uint32_t paramTypes, TEE_Param params[4], void **sessionContext) { paramTypes = paramTypes; sessionContext = sessionContext; params = params; OT_LOG(LOG_DEBUG, "Calling the Open session entry point"); return TEE_SUCCESS; }
TEE_Result TA_EXPORT TA_CreateEntryPoint(void) { OT_LOG(LOG_INFO, "Calling the create entry point"); if (storage_test(2)) return TEE_ERROR_GENERIC; if (crypto_test(2)) return TEE_ERROR_GENERIC; return TEE_SUCCESS; }
void copy_all_attributes(TEE_ObjectHandle srcObj, TEE_ObjectHandle destObj) { size_t i; if (srcObj->attrs_count != destObj->attrs_count) { OT_LOG(LOG_ERR, "Copy fail: Attribute count do not match\n"); return; } for (i = 0; i < srcObj->attrs_count; i++) cpy_attr(srcObj, i, destObj, i); }
int com_get_msg_type(void *msg, uint8_t *msg_type) { struct com_msg_hdr msg_hdr; if (!msg || !msg_type) { OT_LOG(LOG_ERR, "message null"); return 1; } memcpy(&msg_hdr, msg, sizeof(struct com_msg_hdr)); *msg_type = msg_hdr.msg_type; return 0; }
int com_get_msg_sess_id(void *msg, uint64_t *sess_id) { struct com_msg_hdr msg_hdr; if (!msg || !sess_id) { OT_LOG(LOG_ERR, "message null"); return 1; } memcpy(&msg_hdr, msg, sizeof(struct com_msg_hdr)); *sess_id = msg_hdr.sess_id; return 0; }
static TEE_Result check_recv_params(uint32_t paramTypes, TEE_Param *params) { uint32_t i; /* Check parameter type */ if (TEE_PARAM_TYPE_GET(paramTypes, 0) != TEE_PARAM_TYPE_VALUE_INOUT) { OT_LOG(LOG_ERR, "Expected value inout type as index 0 parameter"); return TEE_ERROR_BAD_PARAMETERS; } if (TEE_PARAM_TYPE_GET(paramTypes, 1) != TEE_PARAM_TYPE_MEMREF_INOUT || TEE_PARAM_TYPE_GET(paramTypes, 2) != TEE_PARAM_TYPE_MEMREF_INOUT || TEE_PARAM_TYPE_GET(paramTypes, 3) != TEE_PARAM_TYPE_MEMREF_INOUT) { OT_LOG(LOG_ERR, "Expected buffer inout type as index 1,2,3 parameter"); return TEE_ERROR_BAD_PARAMETERS; } /* Param 0 */ if (params[0].value.a != IN_VALUE_A) { OT_LOG(LOG_ERR, "Not expected parameter at 0 (value a)"); return TEE_ERROR_BAD_PARAMETERS; } if (params[0].value.b != IN_VALUE_B) { OT_LOG(LOG_ERR, "Not expected parameter at 0 (value b)"); return TEE_ERROR_BAD_PARAMETERS; } /* Param 1 & 2 */ for (i = 1; i < 3; i++) { if (SIZE_OF_VEC(in_vector) != params[i].memref.size) { OT_LOG(LOG_ERR, "Not expected parameter at %u (wrong buffer length)", i); return TEE_ERROR_BAD_PARAMETERS; } if (TEE_MemCompare(in_vector, params[1].memref.buffer, params[1].memref.size)) { OT_LOG(LOG_ERR, "Not expected parameter at %u (wrong data)", i); return TEE_ERROR_BAD_PARAMETERS; } } /* Param 3, just length */ if (RAND_BUFFER_SIZE != params[3].memref.size) { OT_LOG(LOG_ERR, "Not expected parameter at 3 (wrong buffer length)"); return TEE_ERROR_BAD_PARAMETERS; } return TEE_SUCCESS; }
int com_get_msg_name(void *msg, uint8_t *msg_name) { /* Not the most optimized operation, but I do not know a better way than * a "hardcoded" solution. */ struct com_msg_hdr msg_hdr; if (!msg || !msg_name) { OT_LOG(LOG_ERR, "message null"); return 1; } memcpy(&msg_hdr, msg, sizeof(struct com_msg_hdr)); *msg_name = msg_hdr.msg_name; return 0; }
void unload_ta(struct ta_interface *callbacks) { if (!callbacks) return; dlerror(); /* Call the TA cleanup routine */ callbacks->destroy(); if (dlclose(callbacks->library)) OT_LOG(LOG_DEBUG, "Error while closing library : %s", dlerror()); TEE_Free(callbacks); return; }
static TEE_Result get_counter_value(uint64_t *mem_data) { TEE_ObjectHandle counter; TEE_Result ret; uint64_t previous_value = 0, next_value = 0; uint32_t bytes_read; /* Open the object here if it exists */ ret = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, &object_id, sizeof(object_id), TEE_DATA_FLAG_ACCESS_READ | TEE_DATA_FLAG_ACCESS_WRITE, &counter); if (ret != TEE_SUCCESS) { OT_LOG(LOG_ERR, "TEE_OpenPersistentObject failed: 0x%x", ret); } else { OT_LOG(LOG_ERR, "TEE_OpenPersistentObject succesful"); ret = TEE_ReadObjectData(counter, (void *)&previous_value, sizeof(uint64_t), &bytes_read); if (ret != TEE_SUCCESS) { OT_LOG(LOG_ERR, "TEE_ReadObjectData failed: 0x%x", ret); goto end_ctr; } *mem_data = previous_value; /* Increment the value */ next_value = ++previous_value; OT_LOG(LOG_ERR, "New counter value: %d", (int)next_value); /* Set data position back to the start of object */ ret = TEE_SeekObjectData(counter, 0, TEE_DATA_SEEK_SET); if (ret != TEE_SUCCESS) { OT_LOG(LOG_ERR, "TEE_SeekObjectData failed: 0x%x", ret); goto end_ctr; } /* Write the new counter value back to the persistent object */ ret = TEE_WriteObjectData(counter, (void *)&next_value, sizeof(uint64_t)); if (ret != TEE_SUCCESS) OT_LOG(LOG_ERR, "TEE_WriteObjectData failed: 0x%x\n", ret); } end_ctr: TEE_CloseObject(counter); return ret; }
void TA_EXPORT TA_CloseSessionEntryPoint(void *sessionContext) { sessionContext = sessionContext; OT_LOG(LOG_INFO, "Calling the Close session entry point"); }
void TA_EXPORT TA_DestroyEntryPoint(void) { OT_LOG(LOG_INFO, "Calling the Destroy entry point"); }
TEE_Result TA_EXPORT TA_CreateEntryPoint(void) { OT_LOG(LOG_INFO, "Calling the create entry point"); return TEE_SUCCESS; }
TEE_Result load_ta(const char *path, struct ta_interface **callbacks) { struct ta_interface tmp_cb; const char *err = NULL; struct internal_api_callbacks internal_api_calls; memset((void *)&tmp_cb, 0, sizeof(struct ta_interface)); *callbacks = NULL; dlerror(); tmp_cb.library = dlopen(path, RTLD_NOW); if (!tmp_cb.library) { OT_LOG(LOG_DEBUG, "Failed to load library : %s : %s", path, dlerror()); return TEE_ERROR_GENERIC; } /* To be a valid TA it must not have any errors when loading the lbrary AND * it MUST provide each of the 5 entry functions listed below!! */ *(void **)(&tmp_cb.create) = dlsym(tmp_cb.library, "TA_CreateEntryPoint"); err = dlerror(); if (err != NULL || !tmp_cb.create) { OT_LOG(LOG_DEBUG, "Failed to find CreateEntryPoint : %s : %s", path, err); goto err_cleanup; } *(void **)(&tmp_cb.destroy) = dlsym(tmp_cb.library, "TA_DestroyEntryPoint"); err = dlerror(); if (err != NULL || !tmp_cb.destroy) { OT_LOG(LOG_DEBUG, "Failed to find DestroyEntryPoint : %s : %s", path, err); goto err_cleanup; } *(void **)(&tmp_cb.open_session) = dlsym(tmp_cb.library, "TA_OpenSessionEntryPoint"); err = dlerror(); if (err != NULL || !tmp_cb.open_session) { OT_LOG(LOG_DEBUG, "Failed to find OpenSessionEntryPoint : %s : %s", path, err); goto err_cleanup; } *(void **)(&tmp_cb.invoke_cmd) = dlsym(tmp_cb.library, "TA_InvokeCommandEntryPoint"); err = dlerror(); if (err != NULL || !tmp_cb.invoke_cmd) { OT_LOG(LOG_DEBUG, "Failed to find InvokeCommandEntryPoint : %s : %s", path, err); goto err_cleanup; } *(void **)(&tmp_cb.close_session) = dlsym(tmp_cb.library, "TA_CloseSessionEntryPoint"); err = dlerror(); if (err != NULL || !tmp_cb.close_session) { OT_LOG(LOG_DEBUG, "Failed to find CloseSession Entry point : %s : %s", path, err); goto err_cleanup; } *callbacks = calloc(1, sizeof(struct ta_interface)); if (!*callbacks) { OT_LOG(LOG_DEBUG, "Out of memory"); goto err_cleanup; } memcpy(*callbacks, (void *)&tmp_cb, sizeof(struct ta_interface)); fill_internal_api_callbacks(&internal_api_calls); reg_internal_api_callbacks(&internal_api_calls); err_cleanup: if (err || !*callbacks) { if (tmp_cb.destroy) tmp_cb.destroy(); dlclose(tmp_cb.library); return TEE_ERROR_GENERIC; } return TEE_SUCCESS; }
int lib_main_loop(struct core_control *ctl_params) { int sockfd[2]; pid_t new_proc_pid; struct com_msg_open_session *recv_open_msg = NULL; struct com_msg_ta_created new_ta_info; int ret, event_count, i; sigset_t sig_empty_set, sig_block_set; struct epoll_event cur_events[MAX_CURR_EVENTS]; struct ta_loop_arg ta_loop_args = {0}; int shm_fds[4]; int shm_fd_count; memset(&new_ta_info, 0, sizeof(struct com_msg_ta_created)); child_stack = calloc(1, CHILD_STACK_SIZE); if (!child_stack) { OT_LOG(LOG_ERR, "Sigempty set failed"); exit(EXIT_FAILURE); } if (sigemptyset(&sig_empty_set)) { OT_LOG(LOG_ERR, "Sigempty set failed"); exit(EXIT_FAILURE); } if (sigfillset(&sig_block_set)) { OT_LOG(LOG_ERR, "Sigempty set failed"); exit(EXIT_FAILURE); } if (init_epoll()) { OT_LOG(LOG_ERR, "Epoll init failure"); exit(EXIT_FAILURE); } /* listen to inbound connections from the manager */ if (epoll_reg_fd(ctl_params->comm_sock_fd, EPOLLIN)) { OT_LOG(LOG_ERR, "Failed reg manager socket"); exit(EXIT_FAILURE); } if (epoll_reg_fd(ctl_params->self_pipe_fd, EPOLLIN)) { OT_LOG(LOG_ERR, "Failed reg self pipe socket"); exit(EXIT_FAILURE); } #ifdef GRACEFUL_TERMINATION /* Cleanup function if process need to be cleaned gracefully */ ctl_params->fn_cleanup_launher = cleanup_launcher; #endif OT_LOG(LOG_ERR, "Entering the launcher mainloop"); for (;;) { if (pthread_sigmask(SIG_SETMASK, &sig_empty_set, NULL)) { OT_LOG(LOG_ERR, "Problem with signal mask setting"); continue; } event_count = wrap_epoll_wait(cur_events, MAX_CURR_EVENTS); if (event_count == -1) { if (errno == EINTR) { check_signal_status(ctl_params); continue; } /* Log error and hope the error clears itself */ OT_LOG(LOG_ERR, "Failed return from epoll_wait"); continue; } if (pthread_sigmask(SIG_SETMASK, &sig_block_set, NULL)) { OT_LOG(LOG_ERR, "Problem with signal mask setting"); continue; } /* Note: All signals are blocked */ for (i = 0; i < event_count; i++) { if (cur_events[i].data.fd == ctl_params->self_pipe_fd) { if (cur_events[i].events & EPOLLERR) { OT_LOG(LOG_ERR, "Something wrong with self pipe"); exit(EXIT_FAILURE); } check_signal_status(ctl_params); continue; } /* Launcher is monitoring only two socket and second one is manager fd */ if (cur_events[i].events & EPOLLERR || cur_events[i].events & EPOLLHUP) { OT_LOG(LOG_ERR, "Manager socket error"); exit(EXIT_FAILURE); } ret = com_recv_msg(ctl_params->comm_sock_fd, (void **)&recv_open_msg, NULL, shm_fds, &shm_fd_count); if (ret == -1) { free(recv_open_msg); /* TODO: Figur out why -1, but for now lets * hope the error clears itself*/ continue; } else if (ret > 0) { /* ignore message */ free(recv_open_msg); continue; } recv_open_msg->msg_hdr.shareable_fd_count = 0; if (shm_fd_count > 0 && shm_fd_count <= 4) { recv_open_msg->msg_hdr.shareable_fd_count = shm_fd_count; memcpy(recv_open_msg->msg_hdr.shareable_fd, shm_fds, sizeof(int)*shm_fd_count); } /* Extrac info from message */ if (recv_open_msg->msg_hdr.msg_name != COM_MSG_NAME_OPEN_SESSION || recv_open_msg->msg_hdr.msg_type != COM_TYPE_QUERY) { OT_LOG(LOG_ERR, "Invalid message"); goto close_fd; } /* Received correct mesage from manager. Prepare response message. * PID is filled later */ new_ta_info.msg_hdr.msg_name = COM_MSG_NAME_CREATED_TA; new_ta_info.msg_hdr.msg_type = COM_TYPE_RESPONSE; new_ta_info.msg_hdr.sess_id = recv_open_msg->msg_hdr.sess_id; /* create a socket pair so the manager and TA can communicate */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) == -1) { OT_LOG(LOG_ERR, "failed to create a socket pair"); send_err_msg_to_manager(ctl_params->comm_sock_fd, &new_ta_info); goto close_fd; } /* * Clone now to create the TA subprocess */ /* Fill ta loop arguments */ ta_loop_args.com_sock = sockfd[1]; ta_loop_args.ctl_params = ctl_params; ta_loop_args.recv_open_msg = recv_open_msg; new_proc_pid = clone(ta_process_loop, child_stack + CHILD_STACK_SIZE, SIGCHLD | CLONE_PARENT, &ta_loop_args); if (new_proc_pid == -1) { send_err_msg_to_manager(ctl_params->comm_sock_fd, &new_ta_info); goto close_pair; } new_ta_info.pid = new_proc_pid; ret = com_send_msg(ctl_params->comm_sock_fd, &new_ta_info, sizeof(struct com_msg_ta_created), NULL, 0); if (ret == sizeof(struct com_msg_ta_created)) { if (send_fd(ctl_params->comm_sock_fd, &sockfd[0], 1, NULL, 0) == -1) { OT_LOG(LOG_ERR, "Failed to send TA sock"); kill(new_proc_pid, SIGKILL); /* TODO: Check what is causing error, but for now * lets hope the error clears itself*/ } } else { OT_LOG(LOG_ERR, "Failed to send response msg"); kill(new_proc_pid, SIGKILL); /* TODO: Check what is causing error, but for now lets * hope the error clears itself*/ } close_pair: /* parent process will stay as the launcher */ close(sockfd[0]); close(sockfd[1]); close_fd: /* close possibly forwarded file descriptors */ while (recv_open_msg->msg_hdr.shareable_fd_count > 0) { recv_open_msg->msg_hdr.shareable_fd_count--; close(recv_open_msg->msg_hdr.shareable_fd [recv_open_msg->msg_hdr.shareable_fd_count]); } free(recv_open_msg); } } }
int ta_process_loop(int man_sockfd, struct com_msg_open_session *open_msg) { int ret; pthread_t ta_logic_thread; pthread_attr_t attr; struct epoll_event cur_events[MAX_CURR_EVENTS]; int event_count, i; char proc_name[MAX_PR_NAME]; /* For now */ sigset_t sig_empty_set; /* Set new ta process name */ strncpy(proc_name, open_msg->ta_so_name, MAX_PR_NAME); prctl(PR_SET_NAME, (unsigned long)proc_name); strncpy(argv0, proc_name, argv0_len); /* Load TA to this process */ ret = load_ta(open_msg->ta_so_name, &interface); if (ret != TEE_SUCCESS || interface == NULL) { OT_LOG(LOG_ERR, "Failed to load the TA"); exit(EXIT_FAILURE); } /* Note: All signal are blocked. Prepare allow set when we can accept signals */ if (sigemptyset(&sig_empty_set)) { OT_LOG(LOG_ERR, "Sigempty set failed: %s", strerror(errno)) exit(EXIT_FAILURE); } /* create an eventfd, that will allow the writer to increment the count by 1 * for each new event, and the reader to decrement by 1 each time, this will allow the * reader to be notified for each new event, as opposed to being notified just once that * there are "event(s)" pending*/ event_fd = eventfd(0, EFD_SEMAPHORE); if (event_fd == -1) { OT_LOG(LOG_ERR, "Failed to initialize eventfd"); exit(EXIT_FAILURE); } /* Initializations of TODO and DONE queues*/ INIT_LIST(&tasks_todo.list); INIT_LIST(&tasks_done.list); /* Init epoll and register FD/data */ if (init_epoll()) exit(EXIT_FAILURE); /* listen to inbound connections from the manager */ if (epoll_reg_fd(man_sockfd, EPOLLIN)) exit(EXIT_FAILURE); /* listen for communications from the TA thread process */ if (epoll_reg_fd(event_fd, EPOLLIN)) exit(EXIT_FAILURE); /* Signal handling */ if (epoll_reg_fd(self_pipe_fd, EPOLLIN)) exit(EXIT_FAILURE); /* Init worker thread */ ret = pthread_attr_init(&attr); if (ret) { OT_LOG(LOG_ERR, "Failed to create attr for thread: %s", strerror(errno)) exit(EXIT_FAILURE); } /* TODO: Should we reserver space for thread stack? */ ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (ret) { OT_LOG(LOG_ERR, "Failed set DETACHED: %s", strerror(errno)) exit(EXIT_FAILURE); } /* Known error: CA can not determ if TA is launched or not, because framework is calling * create entry point and open session function. Those functions return values is mapped * into one return value. */ if (interface->create() != TEE_SUCCESS) { OT_LOG(LOG_ERR, "TA create entry point failed"); exit(EXIT_SUCCESS); } /* Launch worker thread and pass open session message as a parameter */ ret = pthread_create(&ta_logic_thread, &attr, ta_internal_thread, open_msg); if (ret) { OT_LOG(LOG_ERR, "Failed launch thread: %s", strerror(errno)) interface->destroy(); exit(EXIT_FAILURE); } pthread_attr_destroy(&attr); /* Not needed any more */ /* Allow signal delivery */ if (pthread_sigmask(SIG_SETMASK, &sig_empty_set, NULL)) { OT_LOG(LOG_ERR, "failed to allow signals: %s", strerror(errno)) exit(EXIT_FAILURE); } /* Enter into the main part of this io_thread */ for (;;) { event_count = wrap_epoll_wait(cur_events, MAX_CURR_EVENTS); if (event_count == -1) { if (errno == EINTR) { continue; } /* Log error and hope the error clears itself */ OT_LOG(LOG_ERR, "Failed return from epoll_wait"); continue; } for (i = 0; i < event_count; i++) { if (cur_events[i].data.fd == man_sockfd) { receive_from_manager(&cur_events[i], man_sockfd); } else if (cur_events[i].data.fd == event_fd) { reply_to_manager(&cur_events[i], man_sockfd); } else if (cur_events[i].data.fd == self_pipe_fd) { } else { OT_LOG(LOG_ERR, "unknown event source"); } } } /* Should never reach here */ exit(EXIT_FAILURE); }