Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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 */
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
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);
}
Beispiel #11
0
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);
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
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");
	}
}
Beispiel #15
0
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);
}
Beispiel #16
0
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;
}
Beispiel #17
0
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);
}
Beispiel #19
0
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;
}
Beispiel #20
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;
}
Beispiel #21
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;
}
Beispiel #22
0
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;
}
Beispiel #23
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;
}
Beispiel #24
0
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;
}
Beispiel #25
0
void TA_EXPORT TA_CloseSessionEntryPoint(void *sessionContext)
{
	sessionContext = sessionContext;

	OT_LOG(LOG_INFO, "Calling the Close session entry point");
}
Beispiel #26
0
void TA_EXPORT TA_DestroyEntryPoint(void)
{
	OT_LOG(LOG_INFO, "Calling the Destroy entry point");
}
Beispiel #27
0
TEE_Result TA_EXPORT TA_CreateEntryPoint(void)
{
	OT_LOG(LOG_INFO, "Calling the create entry point");

	return TEE_SUCCESS;
}
Beispiel #28
0
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;
}
Beispiel #29
0
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);

		}
	}
}
Beispiel #30
0
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);
}