From 04697a519c336eec3917891294626ed3c67603cc Mon Sep 17 00:00:00 2001 From: Uladzislau Harbuz Date: Fri, 20 Oct 2017 16:32:47 +0200 Subject: [PATCH] Change privileges verification. Revert 'Implement checking of Tizen policies on TA loading.' Check privileges by mapping privilege tee.client to priv_tee_client group. Only application with that privilege will able to use /dev/tee[0-9] devices. Set devices /dev/tee[0-9] group to priv_tee_client with udev rule. Change-Id: I87e476a20434e2022fd4a397f5bd02340940e002 --- libteec/src/tee_client_api.c | 115 +-------------- packaging/tef-optee-client.spec | 49 ++++--- systemd/90-teedaemon.rules | 3 +- systemd/tef-optee.service.in | 2 - tee-supplicant/Makefile | 7 - tee-supplicant/src/security.c | 279 ------------------------------------ tee-supplicant/src/security.h | 74 ---------- tee-supplicant/src/tee_supplicant.c | 101 ++----------- tee-supplicant/src/unix_socket.c | 192 ------------------------- tee-supplicant/src/unix_socket.h | 61 -------- 10 files changed, 39 insertions(+), 844 deletions(-) delete mode 100644 tee-supplicant/src/security.c delete mode 100644 tee-supplicant/src/security.h delete mode 100644 tee-supplicant/src/unix_socket.c delete mode 100644 tee-supplicant/src/unix_socket.h diff --git a/libteec/src/tee_client_api.c b/libteec/src/tee_client_api.c index 2f30a27..a89cb88 100644 --- a/libteec/src/tee_client_api.c +++ b/libteec/src/tee_client_api.c @@ -39,10 +39,6 @@ #include #include #include -#include -#include -#include -#include #ifndef __aligned #define __aligned(x) __attribute__((__aligned__(x))) @@ -53,10 +49,6 @@ /* How many device sequence numbers will be tried before giving up */ #define TEEC_MAX_DEV_SEQ 10 -#define N_MAX_TRY 100000 -/* Time of waiting for server responce, seconds */ -#define WAITING_TIME 90 -#define SOCKET_NAME_LENGTH 100 static pthread_mutex_t teec_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -464,55 +456,6 @@ static void uuid_to_octets(uint8_t d[TEE_IOCTL_UUID_LEN], const TEEC_UUID *s) memcpy(d + 8, s->clockSeqAndNode, sizeof(s->clockSeqAndNode)); } -static int try_connect_to_server(const char* sock_path) -{ - - int sockfd = socket(AF_UNIX, SOCK_STREAM, 0); - if (sockfd < 0) { - EMSG("Error of creating socket."); - return -1; - } - - struct sockaddr_un host_addr; - memset(&host_addr, 0, sizeof(host_addr)); - host_addr.sun_family = AF_UNIX; - strncpy(host_addr.sun_path, sock_path, sizeof(host_addr.sun_path)); - - int res = -1; - - for (int i = 0; i < N_MAX_TRY; ++i) { - res = connect(sockfd, &host_addr, sizeof(host_addr)); - if (res == 0) return sockfd; - } - - EMSG("FAILED: %s", strerror(errno)); - close(sockfd); - return -1; -} - - -struct ioctl_params { - int fd; - unsigned long request; - void* buf; - int ret; -}; - -/* - * It is mechanism of opening dummy unix socket for allow supplicant - * use it for cynara operations. - * It calls ioctl from new thread, supplicant opens socket for this session - * and waits for connection from client, and simultaneously - * current thread of client lib try to connect this socket. - */ -static void* run_ioctl_command(void* data) -{ - struct ioctl_params* params = (struct ioctl_params*)data; - params->ret = ioctl(params->fd, params->request, params->buf); - pthread_exit(NULL); -} - - TEEC_Result TEEC_OpenSession(TEEC_Context *ctx, TEEC_Session *session, const TEEC_UUID *destination, uint32_t connection_method, const void *connection_data, @@ -526,10 +469,9 @@ TEEC_Result TEEC_OpenSession(TEEC_Context *ctx, TEEC_Session *session, struct tee_ioctl_open_session_arg *arg; struct tee_ioctl_param *params; TEEC_Result res; - uint32_t eorig; + uint32_t eorig = TEEC_ORIGIN_API; TEEC_SharedMemory shm[TEEC_CONFIG_PAYLOAD_REF_COUNT]; int rc; - int sockfd = -1; (void)&connection_data; @@ -549,64 +491,15 @@ TEEC_Result TEEC_OpenSession(TEEC_Context *ctx, TEEC_Session *session, uuid_to_octets(arg->uuid, destination); arg->clnt_login = connection_method; - char s_uuid[SOCKET_NAME_LENGTH] = {0}; - sprintf(s_uuid, "/tmp/%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x", - destination->timeLow, - destination->timeMid, - destination->timeHiAndVersion, - destination->clockSeqAndNode[0], - destination->clockSeqAndNode[1], - destination->clockSeqAndNode[2], - destination->clockSeqAndNode[3], - destination->clockSeqAndNode[4], - destination->clockSeqAndNode[5], - destination->clockSeqAndNode[6], - destination->clockSeqAndNode[7] - ); - res = teec_pre_process_operation(ctx, operation, params, shm); if (res != TEEC_SUCCESS) { eorig = TEEC_ORIGIN_API; goto out_free_temp_refs; } - /* Run ioctl in new thread for allow client go to code with connection to - * waiting server*/ - - pthread_t thread; - - struct ioctl_params ioparam; - ioparam.fd = ctx->fd; - ioparam.request = TEE_IOC_OPEN_SESSION; - ioparam.buf = &buf_data; - - rc = pthread_create(&thread, NULL, run_ioctl_command, &ioparam); - if (rc) { - EMSG("Can't create thread"); - goto out_free_temp_refs; - } - - sockfd = try_connect_to_server(s_uuid); - - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += WAITING_TIME; - - rc = pthread_timedjoin_np(thread, NULL, &ts); - if (rc != 0) { - EMSG("No responce from server"); - res = TEEC_ERROR_GENERIC; - goto out_free_temp_refs; - } - - if (sockfd < 0) { - EMSG("Connection to server failed"); - goto out_free_temp_refs; - } - - rc = ioparam.ret; + rc = ioctl(ctx->fd, TEE_IOC_OPEN_SESSION, &buf_data); if (rc) { - EMSG("TEE_IOC_OPEN_SESSION failed: %d", errno); + EMSG("TEE_IOC_OPEN_SESSION failed"); eorig = TEEC_ORIGIN_COMMS; res = ioctl_errno_to_res(errno); goto out_free_temp_refs; @@ -621,8 +514,6 @@ TEEC_Result TEEC_OpenSession(TEEC_Context *ctx, TEEC_Session *session, teec_post_process_operation(operation, params, shm); out_free_temp_refs: - close(sockfd); - unlink(s_uuid); teec_free_temp_refs(operation, shm); out: if (ret_origin) diff --git a/packaging/tef-optee-client.spec b/packaging/tef-optee-client.spec index f9d7d00..68f431d 100644 --- a/packaging/tef-optee-client.spec +++ b/packaging/tef-optee-client.spec @@ -9,31 +9,27 @@ Group: Security/Libraries License: BSD-2-Clause URL: N/A Source0: %{name}-%{version}.tar.gz -Source1: %{name}.manifest +Source1: %{name}.manifest ExclusiveArch: armv6l armv7hl armv7l aarch64 Provides: %{name} BuildRequires: make -BuildRequires: pkgconfig(cynara-client) -BuildRequires: pkgconfig(cynara-creds-socket) -BuildRequires: pkgconfig(cynara-session) -BuildRequires: pkgconfig(security-manager) -BuildRequires: pkgconfig(security-privilege-manager) -BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: cmake Requires: tef-libteec %{?systemd_requires} %define bin_dir %{?TZ_SYS_BIN:%TZ_SYS_BIN}%{!?TZ_SYS_BIN:%_bindir} -%define udev_dir %_libdir/udev/rules.d/ +%define lib_dir %{?TZ_SYS_LIB:%TZ_SYS_LIB}%{!?TZ_SYS_LIB:%_libdir} +%define udev_dir %{lib_dir}/udev/rules.d/ %define build_udev_dir %{buildroot}/%{udev_dir} +%define tastore_dir %{lib_dir}/tastore/ %define build_unit_dir %{buildroot}%{_unitdir} -%define optee_libteec /%{_lib}/tef/optee +%define optee_libteec %{lib_dir}/tef/optee/ %define smack_domain_name System -%define compile_param CROSS_COMPILE="" MAJOR_VERSION="%{major_version}" MINOR_VERSION="%{minor_version}" CFLAGS='-fPIC -D_GNU_SOURCE -I%{_includedir}/cynara' +%define compile_param CROSS_COMPILE="" MAJOR_VERSION="%{major_version}" MINOR_VERSION="%{minor_version}" CFLAGS='-fPIC -D_GNU_SOURCE -DSYS_TA_PATH=\\"%{tastore_dir}\\"' %description TEF Trustzone OpTEE provides daemon to support OpTEE OS solution and libteec library, @@ -49,16 +45,15 @@ make %{compile_param} build cd systemd cmake . \ - -DUDEV_RULES_DIR=%{build_udev_dir} \ - -DSYSTEMD_UNIT_DIR=%{build_unit_dir} \ - -DSYSTEMD_CFG_BIN_DIR=%{bin_dir} \ - -DSMACK_DOMAIN_NAME=%{smack_domain_name} + -DUDEV_RULES_DIR=%{build_udev_dir} \ + -DSYSTEMD_UNIT_DIR=%{build_unit_dir} \ + -DSYSTEMD_CFG_BIN_DIR=%{bin_dir} \ + -DSMACK_DOMAIN_NAME=%{smack_domain_name} cd - %install make %{compile_param} DESTDIR=%{buildroot} LIBDIR=%{optee_libteec} install -mkdir %{buildroot}/%{_prefix} mv %{buildroot}/%{optee_libteec}/libteec.so.%{major_version}.%{minor_version} %{buildroot}/%{optee_libteec}/libteec.so.%{version} mv %{buildroot}/bin %{buildroot}/%{_prefix} cd systemd @@ -66,25 +61,29 @@ make install cd - rm -rf %{buildroot}/include -rm -rf %{buildroot}/%{_libdir}/debug +rm -rf %{buildroot}/%{lib_dir}/debug rm -rf %{buildroot}/%{optee_libteec}/libteec.so.%{major_version} %{buildroot}/%{optee_libteec}/libteec.so -%post -mkdir -p -m 774 %{_libdir}/tastore -chown root:security_fw %{_libdir}/tastore +mkdir -p %{buildroot}/%{tastore_dir} -#./usr/sbin/tef-update.sh optee +%post +tef-update.sh optee ln -sf %{optee_libteec}/libteec.so.%{version} %{optee_libteec}/libteec.so.%{major_version} ln -sf %{optee_libteec}/libteec.so.%{major_version} %{optee_libteec}/libteec.so +chsmack -a _ %{optee_libteec}/libteec.so* %postun -./usr/sbin/tef-update.sh +if [ $1 = 0 ] ; then + tef-update.sh +fi %files +%manifest %{name}.manifest %license LICENSE -%{_bindir}/tee-supplicant -%{_unitdir}/tef-optee.service -%{udev_dir}/90-teedaemon.rules -%{optee_libteec}/libteec.so.%{version} +%attr(111,security_fw,security_fw) %{bin_dir}/tee-supplicant +%attr(770,root,security_fw) %{tastore_dir} +%attr(644,root,root) %{_unitdir}/tef-optee.service +%attr(644,root,root) %{udev_dir}/90-teedaemon.rules +%attr(755,security_fw,security_fw) %{optee_libteec}/libteec.so.%{version} %changelog diff --git a/systemd/90-teedaemon.rules b/systemd/90-teedaemon.rules index 6cf5550..249d8a6 100644 --- a/systemd/90-teedaemon.rules +++ b/systemd/90-teedaemon.rules @@ -1 +1,2 @@ -SUBSYSTEM=="tee", KERNEL=="teepriv*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="tef-optee.service" +SUBSYSTEM=="tee", KERNEL=="teepriv[0-9]", TAG+="systemd", ENV{SYSTEMD_WANTS}+="tef-optee.service" +SUBSYSTEM=="tee", KERNEL=="tee[0-9]", GROUP="priv_tee_client", MODE="0660", SECLABEL{smack}="*" diff --git a/systemd/tef-optee.service.in b/systemd/tef-optee.service.in index 086ed4f..590b242 100644 --- a/systemd/tef-optee.service.in +++ b/systemd/tef-optee.service.in @@ -3,11 +3,9 @@ Description=TEF OpTEE Daemon DefaultDependencies=no After=opt.mount - [Service] User=root Group=security_fw SmackProcessLabel=@SMACK_DOMAIN_NAME@ ExecStart=@SYSTEMD_CFG_BIN_DIR@/tee-supplicant RuntimeDirectory=@SERVICE_NAME@ -StandardOutput=journal diff --git a/tee-supplicant/Makefile b/tee-supplicant/Makefile index 73f9936..6d24c9f 100644 --- a/tee-supplicant/Makefile +++ b/tee-supplicant/Makefile @@ -19,8 +19,6 @@ TEES_SRCS := tee_supplicant.c \ tee_supp_fs.c \ rpmb.c \ handle.c \ - security.c \ - unix_socket.c \ ../../libteec/src/teec_trace.c @@ -83,11 +81,6 @@ endif TEES_LDFLAGS += -lpthread # Needed to get clock_gettime() for for glibc versions before 2.17 TEES_LDFLAGS += -lrt -TEES_LDFLAGS += -lcynara-creds-socket -TEES_LDFLAGS += -lcynara-client -TEES_LDFLAGS += -lcynara-session -TEES_LDFLAGS += -lsecurity-manager-client -TEES_LDFLAGS += -ltzplatform-config-2.0 tee-supplicant: $(TEES_FILE) diff --git a/tee-supplicant/src/security.c b/tee-supplicant/src/security.c deleted file mode 100644 index e7c7034..0000000 --- a/tee-supplicant/src/security.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2017, Samsung Electronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include "security.h" -#include -#include -#include -#include - - -/* Global instance of cynara. Get it by function get_cynara_instance, DO NOT USE IT directly! */ -static cynara *p_cynara = NULL; - -#define CYNARA_CACHE_SIZE 100U -#define RETURN_UNLOCK(ret, mtx) {pthread_mutex_unlock(&mtx); return ret; } - -static const char* system_ta_paths[] = { - SYS_TA_PATH, -}; - -pthread_mutex_t cynara_mutex = PTHREAD_MUTEX_INITIALIZER; - -const size_t n_sys_ta_paths = sizeof(system_ta_paths)/sizeof(system_ta_paths[0]); - - -/* Call it before locking cynara */ -static cynara* get_cynara_instance() -{ - if (p_cynara == NULL) { - pthread_mutex_lock(&cynara_mutex); - int ret = -1; - cynara_configuration *p_conf = NULL; - - ret = cynara_configuration_create(&p_conf); - if (ret != CYNARA_API_SUCCESS) { - EMSG("Cynara configuration initialization failed"); - RETURN_UNLOCK(NULL, cynara_mutex); - } - - ret = cynara_configuration_set_cache_size(p_conf, CYNARA_CACHE_SIZE); - if (ret != CYNARA_API_SUCCESS) { - EMSG("Set cynara cache size failed"); - RETURN_UNLOCK(NULL, cynara_mutex); - } - - ret = cynara_initialize(&p_cynara, p_conf); - if (ret != CYNARA_API_SUCCESS) { - p_cynara = NULL; - EMSG("Cynara initialize faied"); - RETURN_UNLOCK(NULL, cynara_mutex); - } - - RETURN_UNLOCK(p_cynara, cynara_mutex); - } - - return p_cynara; -} - - -static bool file_exists(const char* fname) -{ - return access(fname, F_OK) == 0; -} - - -static bool get_ca_full_path_from_fd(int caFd, char* path) -{ - - pid_t ca_pid = -1; - int ret = -1; - - char ca_path[MAX_PATH_LENGTH] = {0}; - - enum tzplatform_variable ids[] = {TZ_USER_APP, TZ_SYS_RW_APP, TZ_SYS_RO_APP}; - const size_t N_IDS = sizeof(ids)/sizeof(*ids); - - struct ucred ucred; - int len = sizeof(struct ucred); - - if (getsockopt(caFd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) { - EMSG("Can't get client's uid"); - return false; - } - - struct tzplatform_context *ctx; - if (tzplatform_context_create(&ctx) != 0) { - EMSG("Can not create tizen context"); - return false; - } - - if (tzplatform_context_set_user(ctx, ucred.uid) != 0) { - EMSG("Can not set user for context"); - tzplatform_context_destroy(ctx); - return false; - } - - for (int i = 0; i < N_IDS; ++i) { - strncpy(ca_path, tzplatform_context_getenv(ctx, ids[i]), MAX_PATH_LENGTH); - if (strlen(ca_path) > 0) break; - } - - ret = readlink(ca_path, path, MAX_PATH_LENGTH); - - if (ret == -1) { - EMSG("readlink() failed"); - tzplatform_context_destroy(ctx); - return false; - } - - tzplatform_context_destroy(ctx); - return true; -} - - -bool find_requested_ta(int ca_fd, const char* ta_name, char** allowed_path) -{ - int ret; - char* pkg_id_ca; - *allowed_path = NULL; - - ret = security_manager_identify_app_from_socket(ca_fd, &pkg_id_ca, NULL); - - if (ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT) { - DMSG("Owner of socket has no pkgid"); - - char ta_full_path[MAX_PATH_LENGTH] = {0}; - - /* Check if any of system ta directories contains our ta */ - for (int i = 0; i < n_sys_ta_paths; ++i) { - snprintf(ta_full_path, MAX_PATH_LENGTH, "%s/%s", system_ta_paths[i], ta_name); - - if (file_exists(ta_full_path)) { - *allowed_path = (char*)calloc(strlen(system_ta_paths[i])+1, sizeof(**allowed_path)); - strcpy(*allowed_path, system_ta_paths[i]); - return true; - } - - memset(ta_full_path, 0, MAX_PATH_LENGTH); - } - - return false; - } - - if (ret != SECURITY_MANAGER_SUCCESS) { - EMSG("security_manager_identify_app_from_socket failed with CA"); - return false; - } - - free(pkg_id_ca); - - char ca_pkg_path[MAX_PATH_LENGTH]; - if (!get_ca_full_path_from_fd(ca_fd, ca_pkg_path)) { - EMSG("Error while loading client's path"); - return false; - } - - strncat(ca_pkg_path, TA_LOCAL_PATH, MAX_PATH_LENGTH - strlen(ca_pkg_path)); - char ta_full_path[MAX_PATH_LENGTH] = {0}; - snprintf(ta_full_path, MAX_PATH_LENGTH, "%s/%s", ca_pkg_path, ta_name); - - if (!file_exists(ta_full_path)) { - EMSG("TA %s not found in res/tee/", ta_name); - return false; - } - - return true; -} - - -bool client_has_cynara_permission(int ca_fd, const char *privelege) -{ - cynara *cynara = get_cynara_instance(); - if (cynara == NULL) { - EMSG("Cynara is not initialized"); - return false; - } - - int ret = -1; - char *user = NULL; - char *session = NULL; - char *label = NULL; - pid_t ca_pid = -1; - - pthread_mutex_lock(&cynara_mutex); - - ret = cynara_creds_socket_get_client(ca_fd, CLIENT_METHOD_SMACK, &label); - if (ret != CYNARA_API_SUCCESS) { - EMSG("Couldn't get smack label of the client. Error code: %d", ret); - goto exit_error3; - } - - ret = cynara_creds_socket_get_pid(ca_fd, &ca_pid); - if (ret != CYNARA_API_SUCCESS) { - EMSG("Couldn't get pid of the client. Error code: %d", ret); - goto exit_error2; - } - - session = cynara_session_from_pid(ca_pid); - if (!session) { - EMSG("Couldn't get client's cynara session."); - goto exit_error2; - } - - ret = cynara_creds_socket_get_user(ca_fd, USER_METHOD_DEFAULT, &user); - if (ret != CYNARA_API_SUCCESS) { - EMSG("Couldn't get user. Error code: %d", ret); - goto exit_error1; - } - - ret = cynara_check(cynara, label, session, user, privelege); - if (ret == CYNARA_API_ACCESS_DENIED) { - EMSG("Cynara access denied."); - goto exit_error0; - } else - if (ret != CYNARA_API_ACCESS_ALLOWED) { - EMSG("Error during cynara_check(). Error code: %d", ret); - goto exit_error0; - } - - - ret = cynara_finish(cynara); - if (ret != CYNARA_API_SUCCESS) { - EMSG("Cynara finish failed with error code %d", ret); - } - - free(session); - free(label); - free(user); - pthread_mutex_unlock(&cynara_mutex); - - return true; - -exit_error0: - free(user); - -exit_error1: - free(session); - -exit_error2: - free(label); - -exit_error3: - pthread_mutex_unlock(&cynara_mutex); - - return false; -} diff --git a/tee-supplicant/src/security.h b/tee-supplicant/src/security.h deleted file mode 100644 index 2c661a0..0000000 --- a/tee-supplicant/src/security.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2017, Samsung Electronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - - -#ifndef SECURITY_H -#define SECURITY_H - -#include - -#define MAX_PATH_LENGTH 100 -#define MAX_OPENED_FD 5 - -#ifdef __cplusplus -extern "C" { -#endif - -#define SYS_TA_PATH "/usr/lib/tastore" -#define TA_LOCAL_PATH "/res/tee" - -/** - * This function try to find TA by its name in allowed for client (given by - * socket's file descriptor) by security policies directories. - * - * @param ca_fd File descriptor to opened socket for client. - * @param ta_name Name of ta to connect for. - * @param allowed_ta_path Out parameter, if function returns true, it - * contains found path to TA with given name, - * otherwise pointer is NULL. - * User must free it after use. - * @return true if TA was found, otherwise false. - */ -bool find_requested_ta(int ca_fd, const char* ta_name, char** allowed_ta_path); - -/** - * Check if client given by socket file descriptor has Tizen permission - * for use TEE. - * - * @param ca_fd File descriptor to opened socket for client. - * @param privelege Privilege to check for. - * @return true if client has permission, otherwise false. - */ -bool client_has_cynara_permission(int ca_fd, const char* privilege); - -#ifdef __cplusplus -} -#endif - - -#endif /* SECURITY_H */ diff --git a/tee-supplicant/src/tee_supplicant.c b/tee-supplicant/src/tee_supplicant.c index f98de5a..874b1c1 100644 --- a/tee-supplicant/src/tee_supplicant.c +++ b/tee-supplicant/src/tee_supplicant.c @@ -53,8 +53,6 @@ #include #include #include -#include -#include #include "optee_msg_supplicant.h" @@ -64,7 +62,6 @@ #include #define RPC_NUM_PARAMS 5 -#define MAX_TA_NAME_LENGTH 40 #define RPC_BUF_SIZE (sizeof(struct tee_iocl_supp_send_arg) + \ RPC_NUM_PARAMS * sizeof(struct tee_ioctl_param)) @@ -77,6 +74,10 @@ #define RPC_CMD_SQL_FS 8 #define RPC_CMD_GPROF 9 +#ifndef SYS_TA_PATH +#define SYS_TA_PATH "/usr/lib/tastore/" +#endif + union tee_rpc_invoke { uint64_t buf[(RPC_BUF_SIZE - 1) / sizeof(uint64_t) + 1]; struct tee_iocl_supp_recv_arg recv; @@ -97,8 +98,6 @@ struct thread_arg { pthread_mutex_t mutex; }; -static struct sock_data* open_sock_list[MAX_TA_NUMBER]; - static pthread_mutex_t shm_mutex = PTHREAD_MUTEX_INITIALIZER; static struct tee_shm *shm_head; @@ -260,56 +259,6 @@ static void uuid_from_octets(TEEC_UUID *d, const uint8_t s[TEE_IOCTL_UUID_LEN]) memcpy(d->clockSeqAndNode, s + 8, sizeof(d->clockSeqAndNode)); } -/* Returns TEEC_SUCCESS if client with uuid has all needed permissions. - * Othwrwise returns TEEC_Result error code - * uuid - UUID of called TA. - * ta_dir - output parameter. If access for TA allowed, it will contain - * path for it, otherwise it is NULL.*/ -static TEEC_Result allow_access(char* uuid, char** ta_dir) -{ - int ca_fd = -1; - const char* permission = "http://tizen.org/privilege/tee.client"; - struct stat sb; - - char path[MAX_PATH_LENGTH] = {0}; - sprintf(path, SOCK_PATH_PREFIX"%s", uuid); - - if ((stat(path, &sb) == 0) && S_ISSOCK(sb.st_mode)) { - DMSG("We verified this connection already."); - if (get_allowed_path(path, ta_dir, &open_sock_list) < 0) { - EMSG("Socket existes but hasn't allowed path."); - return TEEC_ERROR_GENERIC; - } - return TEEC_SUCCESS; - } - ca_fd = open_socket_for_ca(path, &open_sock_list); - if (ca_fd < 0) { - EMSG("Open socket error"); - return TEEC_ERROR_GENERIC; - } - - char ta_name[MAX_TA_NAME_LENGTH]; - snprintf(ta_name, MAX_TA_NAME_LENGTH, "%s.ta", uuid); - - if (!client_has_cynara_permission(ca_fd, permission)) { - EMSG("Client has no permission to use TEE"); - close(ca_fd); - return TEEC_ERROR_ACCESS_DENIED; - } - - if (!find_requested_ta(ca_fd, ta_name, ta_dir)) { - EMSG("Access deny for TA %s", ta_name); - close(ca_fd); - return TEEC_ERROR_ITEM_NOT_FOUND; - } - - if (set_allowed_path(path, *ta_dir, &open_sock_list) < 0) { - EMSG("Setting allowed path has failed."); - return TEEC_ERROR_GENERIC; - } - return TEEC_SUCCESS; -} - static uint32_t load_ta(size_t num_params, struct tee_ioctl_param *params) { int ta_found = 0; @@ -317,7 +266,6 @@ static uint32_t load_ta(size_t num_params, struct tee_ioctl_param *params) TEEC_UUID uuid; struct tee_ioctl_param_value *val_cmd; TEEC_SharedMemory shm_ta; - TEEC_Result res = -1; memset(&shm_ta, 0, sizeof(shm_ta)); @@ -327,30 +275,8 @@ static uint32_t load_ta(size_t num_params, struct tee_ioctl_param *params) uuid_from_octets(&uuid, (void *)val_cmd); - char s_uuid[MAX_TA_NAME_LENGTH] = {0}; - sprintf(s_uuid, "%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x", - uuid.timeLow, - uuid.timeMid, - uuid.timeHiAndVersion, - uuid.clockSeqAndNode[0], - uuid.clockSeqAndNode[1], - uuid.clockSeqAndNode[2], - uuid.clockSeqAndNode[3], - uuid.clockSeqAndNode[4], - uuid.clockSeqAndNode[5], - uuid.clockSeqAndNode[6], - uuid.clockSeqAndNode[7] - ); - - char *ta_dir = NULL; - res = allow_access(s_uuid, &ta_dir); - if (res != TEEC_SUCCESS) { - return res; - } - size = shm_ta.size; - ta_found = TEECI_LoadSecureModule(ta_dir, &uuid, shm_ta.buffer, &size); - //free(ta_dir); + ta_found = TEECI_LoadSecureModule(SYS_TA_PATH, &uuid, shm_ta.buffer, &size); if (ta_found != TA_BINARY_FOUND) { EMSG(" TA not found"); return TEEC_ERROR_ITEM_NOT_FOUND; @@ -402,7 +328,7 @@ static uint32_t process_alloc(int fd, size_t num_params, shm->id = data.id; shm->size = data.size; - val->c = data.id; + val->c = (uint64_t)data.id; push_tshm(shm); return TEEC_SUCCESS; @@ -414,13 +340,6 @@ static uint32_t process_free(size_t num_params, struct tee_ioctl_param *params) struct tee_shm *shm; int id; - /* Close all unlinked sockets */ - for (int i = 0; i < MAX_TA_NUMBER; ++i) { - if (open_sock_list[i] && access(open_sock_list[i]->addr, F_OK) == -1) { - close_socket_by_addr(open_sock_list[i]->addr, &open_sock_list); - } - } - if (num_params != 1 || get_value(num_params, params, 0, &val)) return TEEC_ERROR_BAD_PARAMETERS; @@ -520,9 +439,9 @@ static bool write_response(int fd, union tee_rpc_invoke *request) struct tee_ioctl_buf_data data; data.buf_ptr = (uintptr_t)&request->send; - data.buf_len = sizeof(struct tee_iocl_supp_send_arg) + - sizeof(struct tee_ioctl_param) * - request->send.num_params; + data.buf_len = (uint64_t)sizeof(struct tee_iocl_supp_send_arg) + + (uint64_t)sizeof(struct tee_ioctl_param) * + (uint64_t)request->send.num_params; if (ioctl(fd, TEE_IOC_SUPPL_SEND, &data)) { EMSG("TEE_IOC_SUPPL_SEND: %s", strerror(errno)); return false; @@ -562,7 +481,7 @@ static bool find_params(union tee_rpc_invoke *request, uint32_t *func, static bool spawn_thread(struct thread_arg *arg) { - pthread_t tid; + pthread_t tid = {0}; int e; DMSG("Spawning a new thread"); diff --git a/tee-supplicant/src/unix_socket.c b/tee-supplicant/src/unix_socket.c deleted file mode 100644 index c49b43a..0000000 --- a/tee-supplicant/src/unix_socket.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2017, Samsung Electronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - - -#include "unix_socket.h" -#include -#include -#include -#include - -#define WAIT_SEC 10 - - -int get_allowed_path(const char *path, char **allowed_path, struct sock_data* open_sockets[]) -{ - for (int i = 0; i < MAX_TA_NUMBER; ++i) { - if (open_sockets[i] && strcmp(path, open_sockets[i]->addr) == 0) { - *allowed_path = open_sockets[i]->allowed_path; - return 0; - } - } - return -1; -} - -int set_allowed_path(const char *path, const char *allowed_path, struct sock_data* open_sockets[]) -{ - for (int i = 0; i < MAX_TA_NUMBER; ++i) { - if (open_sockets[i] && strcmp(path, open_sockets[i]->addr) == 0) { - asprintf(&(open_sockets[i]->allowed_path), "%s", allowed_path); - return 0; - } - } - return -1; -} - -int open_socket_for_ca(const char *path, struct sock_data* open_sockets[]) -{ - int sockfd = -1; - int newsockfd = -1; - int portno = 0; - int free_index = -1; - - if (access(path, F_OK) == -1) { - DMSG("Socket file doesn't exist. Creating"); - close_socket_by_addr(path, open_sockets); - } - - /* check if this socket already open and find first free place in array */ - for (int i = 0; i < MAX_TA_NUMBER; ++i) { - if (open_sockets[i] == NULL && free_index == -1) free_index = i; - if (open_sockets[i] && strcmp(path, open_sockets[i]->addr) == 0) { - DMSG("Socket already exists"); - return open_sockets[i]->fd; - } - } - - if (free_index < 0 || free_index >= MAX_TA_NUMBER) { - EMSG("Limit of simultaneously opened TA is reached"); - return -1; - } - - struct sockaddr_un serv_addr; - int ret = -1; - - sockfd = socket(AF_UNIX, SOCK_STREAM, portno); - if (sockfd < 0) { - EMSG("Couldn't open socket"); - return sockfd; - } - - bzero((char*) &serv_addr, sizeof(serv_addr)); - - serv_addr.sun_family = AF_UNIX; - strncpy(serv_addr.sun_path, path, sizeof(serv_addr) - 1); - - int yes = 1; - ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); - if (ret < 0) { - EMSG("Configure socket error: %s", strerror(errno)); - return ret; - } - - ret = bind(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr)); - if (ret < 0) { - EMSG("Binding of socket adress failed with error: %s", strerror(errno)); - return ret; - } - - char mode[] = "0777"; - int imode = strtol(mode, NULL, 8); - ret = chmod(path, imode); - if (ret != 0) { - EMSG("Error changing permission for socket: %s", strerror(errno)); - return -1; - } - - listen(sockfd, N_CONNECTIONS); - - DMSG("Waiting for accept..."); - - /* Set timeout for waiting for connection from client */ - struct timeval tv; - tv.tv_sec = WAIT_SEC; - tv.tv_usec = 0; - fd_set fds; - - FD_ZERO(&fds); - FD_SET(sockfd, &fds); - - ret = select(sockfd + 1, &fds, NULL, NULL, &tv); - if (ret == -1) { - EMSG("ERROR of select socket: %s", strerror(errno)); - close(newsockfd); - close(sockfd); - unlink(path); - return -1; - } - - if (ret == 0) { - EMSG("Server timeout"); - close(newsockfd); - close(sockfd); - unlink(path); - return -1; - } - - newsockfd = accept(sockfd, NULL, NULL); - if (newsockfd < 0) { - EMSG("Open socket failed"); - } - - open_sockets[free_index] = (struct sock_data*)malloc(sizeof(struct sock_data)); - open_sockets[free_index]->addr = (char*)calloc(strlen(path), sizeof(char)); - strcpy(open_sockets[free_index]->addr, path); - open_sockets[free_index]->fd = newsockfd; - open_sockets[free_index]->parent_fd = sockfd; - - return newsockfd; -} - -int close_socket_by_addr(const char* path, struct sock_data* open_sockets[]) -{ - int index = -1; - - for (int i = 0; i < MAX_TA_NUMBER; ++i) { - if (open_sockets[i] && strcmp(open_sockets[i]->addr, path) == 0) { - index = i; - break; - } - } - - if (index < 0 || index >= MAX_TA_NUMBER) { - EMSG("Could't find socket %s", path); - return -1; - } - - close(open_sockets[index]->fd); - close(open_sockets[index]->parent_fd); - unlink(open_sockets[index]->addr); - - free(open_sockets[index]->addr); - open_sockets[index]->addr = NULL; - free(open_sockets[index]); - open_sockets[index] = NULL; - - return 0; -} diff --git a/tee-supplicant/src/unix_socket.h b/tee-supplicant/src/unix_socket.h deleted file mode 100644 index 9137e68..0000000 --- a/tee-supplicant/src/unix_socket.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2017, Samsung Electronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -#ifndef __UNIX_SOCKET_H -#define __UNIX_SOCKET_H - -#include -#include -#include -#include - -#define MAX_PATH_LENGTH 100 -#define N_CONNECTIONS 5 -#define MAX_TA_NUMBER 10 -#define SOCK_PATH_PREFIX "/tmp/" - -struct sock_data -{ - int fd, parent_fd; - char* addr; - char* allowed_path; -}; - -int get_allowed_path(const char *path, char **allowed_path, struct sock_data* open_sockets[]); - -int set_allowed_path(const char *path, const char *allowed_path, struct sock_data* open_sockets[]); - -/* Open socket on adress /tmp/ca_id and add it to the list of open sockets - * Returns file descriptor of opened socket - * struct sock_data* conn_list[] - list of open sockets which add new socket to*/ -int open_socket_for_ca(const char* ca_id, struct sock_data* conn_list[] ); - -/* Close socket by given path of its file. Returns 0 on success, -1 on error*/ -int close_socket_by_addr(const char* path, struct sock_data* conn_list[]); - -#endif /*__UNIX_SOCKET_H */ -- 2.7.4