diff options
-rw-r--r-- | Android.mk | 4 | ||||
-rw-r--r-- | Kbuild | 2 | ||||
-rw-r--r-- | qseecom/compat_qseecom.c | 943 | ||||
-rw-r--r-- | qseecom/compat_qseecom.h | 341 | ||||
-rw-r--r-- | qseecom/qseecom.c | 206 | ||||
-rw-r--r-- | smcinvoke/trace_smcinvoke.h | 2 |
6 files changed, 1327 insertions, 171 deletions
@@ -19,9 +19,9 @@ endif #TARGET_BOARD_AUTO ifeq ($(ENABLE_SECUREMSM_DLKM), true) LOCAL_PATH := $(call my-dir) -DLKM_DIR := $(TOP)/device/qcom/common/dlkm +DLKM_DIR := $(TOP)/$(BOARD_COMMON_DIR)/dlkm -SEC_KERNEL_DIR := $(TOP)/vendor/qcom/opensource/securemsm-kernel +SEC_KERNEL_DIR := $(TOP)/$(BOARD_OPENSOURCE_DIR)/securemsm-kernel SSG_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/*) \ @@ -12,7 +12,7 @@ ifneq (, $(filter y, $(CONFIG_QTI_QUIN_GVM) $(CONFIG_ARCH_KHAJE) $(CONFIG_ARCH_S LINUXINCLUDE += -include $(SSG_MODULE_ROOT)/config/sec-kernel_defconfig_qseecom.h obj-$(CONFIG_QSEECOM) += qseecom_dlkm.o - qseecom_dlkm-objs := qseecom/qseecom.o + qseecom_dlkm-objs := qseecom/qseecom.o qseecom/compat_qseecom.o endif include $(SSG_MODULE_ROOT)/config/sec-kernel_defconfig_smcinvoke.conf diff --git a/qseecom/compat_qseecom.c b/qseecom/compat_qseecom.c new file mode 100644 index 0000000..49b97c6 --- /dev/null +++ b/qseecom/compat_qseecom.c @@ -0,0 +1,943 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2014-2018, 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include <linux/debugfs.h> +#include <linux/uaccess.h> +#include <linux/qseecom.h> +#include <linux/compat.h> +#include <linux/mman.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/kernel.h> +#include <linux/dmapool.h> +#include <linux/interrupt.h> +#include <linux/spinlock.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/scatterlist.h> +#include <linux/interconnect.h> +#include <linux/delay.h> +#include "compat_qseecom.h" + + +static int compat_get_qseecom_register_listener_req( + struct compat_qseecom_register_listener_req __user *data32, + struct qseecom_register_listener_req *data) +{ + int err; + compat_ulong_t listener_id; + compat_long_t ifd_data_fd; + compat_uptr_t virt_sb_base; + compat_ulong_t sb_size; + + err = get_user(listener_id, &data32->listener_id); + memcpy( &data->listener_id, &listener_id, sizeof(listener_id)); + err |= get_user(ifd_data_fd, &data32->ifd_data_fd); + memcpy( &data->ifd_data_fd, &ifd_data_fd, sizeof(ifd_data_fd)); + err |= get_user(virt_sb_base, &data32->virt_sb_base); + data->virt_sb_base = NULL; + memcpy(&data->virt_sb_base, &virt_sb_base, sizeof(virt_sb_base)); + err |= get_user(sb_size, &data32->sb_size); + memcpy( &data->sb_size, &sb_size, sizeof(sb_size)); + return err; +} + +static int compat_get_qseecom_load_img_req( + struct compat_qseecom_load_img_req __user *data32, + struct qseecom_load_img_req *data) +{ + int err; + compat_ulong_t mdt_len; + compat_ulong_t img_len; + compat_long_t ifd_data_fd; + compat_ulong_t app_arch; + compat_uint_t app_id; + char img_name; + unsigned int i; + + err = get_user(mdt_len, &data32->mdt_len); + memcpy( &data->mdt_len, &mdt_len, sizeof(mdt_len)); + err |= get_user(img_len, &data32->img_len); + memcpy( &data->img_len, &img_len, sizeof(img_len)); + err |= get_user(ifd_data_fd, &data32->ifd_data_fd); + memcpy( &data->ifd_data_fd, &ifd_data_fd, sizeof(ifd_data_fd)); + for (i = 0; i < MAX_APP_NAME_SIZE; i++) { + err |= get_user(img_name, &(data32->img_name[i])); + memcpy( &data->img_name[i], &img_name, sizeof(img_name)); + } + err |= get_user(app_arch, &data32->app_arch); + memcpy( &data->app_arch, &app_arch, sizeof(app_arch)); + err |= get_user(app_id, &data32->app_id); + memcpy( &data->app_id, &app_id, sizeof(app_id)); + return err; +} + +static int compat_get_qseecom_send_cmd_req( + struct compat_qseecom_send_cmd_req __user *data32, + struct qseecom_send_cmd_req *data) +{ + int err; + compat_uptr_t cmd_req_buf; + compat_uint_t cmd_req_len; + compat_uptr_t resp_buf; + compat_uint_t resp_len; + + err = get_user(cmd_req_buf, &data32->cmd_req_buf); + data->cmd_req_buf = NULL; + memcpy( &data->cmd_req_buf, &cmd_req_buf, sizeof(cmd_req_buf)); + err |= get_user(cmd_req_len, &data32->cmd_req_len); + memcpy( &data->cmd_req_len, &cmd_req_len, sizeof(cmd_req_len)); + err |= get_user(resp_buf, &data32->resp_buf); + data->resp_buf = NULL; + memcpy( &data->resp_buf, &resp_buf, sizeof(resp_buf)); + err |= get_user(resp_len, &data32->resp_len); + memcpy( &data->resp_len, &resp_len, sizeof(resp_len)); + return err; +} + +static int compat_get_qseecom_send_modfd_cmd_req( + struct compat_qseecom_send_modfd_cmd_req __user *data32, + struct qseecom_send_modfd_cmd_req *data) +{ + int err; + unsigned int i; + compat_uptr_t cmd_req_buf; + compat_uint_t cmd_req_len; + compat_uptr_t resp_buf; + compat_uint_t resp_len; + compat_long_t fd; + compat_ulong_t cmd_buf_offset; + + err = get_user(cmd_req_buf, &data32->cmd_req_buf); + data->cmd_req_buf = NULL; + memcpy( &data->cmd_req_buf, &cmd_req_buf, sizeof(cmd_req_buf)); + err |= get_user(cmd_req_len, &data32->cmd_req_len); + memcpy(&data->cmd_req_len, &cmd_req_len, sizeof(cmd_req_len)); + err |= get_user(resp_buf, &data32->resp_buf); + data->resp_buf = NULL; + memcpy(&data->resp_buf, &resp_buf, sizeof(resp_buf)); + err |= get_user(resp_len, &data32->resp_len); + memcpy( &data->resp_len, &resp_len, sizeof(resp_len)); + for (i = 0; i < MAX_ION_FD; i++) { + err |= get_user(fd, &data32->ifd_data[i].fd); + memcpy(&data->ifd_data[i].fd, &fd, sizeof(fd)); + err |= get_user(cmd_buf_offset, + &data32->ifd_data[i].cmd_buf_offset); + memcpy(&data->ifd_data[i].cmd_buf_offset, &cmd_buf_offset, sizeof(cmd_buf_offset)); + } + return err; +} + +static int compat_get_qseecom_set_sb_mem_param_req( + struct compat_qseecom_set_sb_mem_param_req __user *data32, + struct qseecom_set_sb_mem_param_req *data) +{ + int err; + compat_long_t ifd_data_fd; + compat_uptr_t virt_sb_base; + compat_ulong_t sb_len; + + err = get_user(ifd_data_fd, &data32->ifd_data_fd); + memcpy(&data->ifd_data_fd, &ifd_data_fd, sizeof(ifd_data_fd)); + err |= get_user(virt_sb_base, &data32->virt_sb_base); + data->virt_sb_base = NULL; + memcpy(&data->virt_sb_base, &virt_sb_base, sizeof(virt_sb_base)); + err |= get_user(sb_len, &data32->sb_len); + memcpy(&data->sb_len, &sb_len, sizeof(sb_len)); + return err; +} + +static int compat_get_qseecom_qseos_version_req( + struct compat_qseecom_qseos_version_req __user *data32, + struct qseecom_qseos_version_req *data) +{ + int err; + compat_uint_t qseos_version; + + err = get_user(qseos_version, &data32->qseos_version); + memcpy( &data->qseos_version, &qseos_version, sizeof(qseos_version)); + return err; +} + +static int compat_get_qseecom_qseos_app_load_query( + struct compat_qseecom_qseos_app_load_query __user *data32, + struct qseecom_qseos_app_load_query *data) +{ + int err = 0; + unsigned int i; + compat_uint_t app_id; + char app_name; + compat_ulong_t app_arch; + + for (i = 0; i < MAX_APP_NAME_SIZE; i++) { + err |= get_user(app_name, &(data32->app_name[i])); + memcpy(&data->app_name[i], &app_name, sizeof(app_name)); + } + err |= get_user(app_id, &data32->app_id); + memcpy(&data->app_id, &app_id, sizeof(app_id)); + err |= get_user(app_arch, &data32->app_arch); + memcpy(&data->app_arch, &app_arch, sizeof(app_arch)); + return err; +} + +static int compat_get_qseecom_send_svc_cmd_req( + struct compat_qseecom_send_svc_cmd_req __user *data32, + struct qseecom_send_svc_cmd_req *data) +{ + int err; + compat_ulong_t cmd_id; + compat_uptr_t cmd_req_buf; + compat_uint_t cmd_req_len; + compat_uptr_t resp_buf; + compat_uint_t resp_len; + + err = get_user(cmd_id, &data32->cmd_id); + memcpy(&data->cmd_id, &cmd_id, sizeof(cmd_id)); + err |= get_user(cmd_req_buf, &data32->cmd_req_buf); + data->cmd_req_buf = NULL; + memcpy(&data->cmd_req_buf, &cmd_req_buf, sizeof(cmd_req_buf)); + err |= get_user(cmd_req_len, &data32->cmd_req_len); + memcpy(&data->cmd_req_len, &cmd_req_len, sizeof(cmd_req_len)); + err |= get_user(resp_buf, &data32->resp_buf); + data->resp_buf = NULL; + memcpy(&data->resp_buf, &resp_buf, sizeof(resp_buf)); + err |= get_user(resp_len, &data32->resp_len); + memcpy(&data->resp_len, &resp_len, sizeof(resp_len)); + return err; +} + +static int compat_get_qseecom_create_key_req( + struct compat_qseecom_create_key_req __user *data32, + struct qseecom_create_key_req *data) +{ + int err = 0; + compat_uint_t usage; + unsigned char hash32; + unsigned int i; + + for (i = 0; i < QSEECOM_HASH_SIZE; i++) { + err |= get_user(hash32, &(data32->hash32[i])); + memcpy( &data->hash32[i], &hash32, sizeof(hash32)); + } + err = get_user(usage, &data32->usage); + memcpy(&data->usage, &usage, sizeof(usage)); + + return err; +} + +static int compat_get_qseecom_wipe_key_req( + struct compat_qseecom_wipe_key_req __user *data32, + struct qseecom_wipe_key_req *data) +{ + int err; + compat_uint_t usage; + compat_int_t wipe_key_flag; + + err = get_user(usage, &data32->usage); + memcpy(&data->usage, &usage, sizeof(usage)); + err |= get_user(wipe_key_flag, &data32->wipe_key_flag); + memcpy(&data->wipe_key_flag, &wipe_key_flag, sizeof(wipe_key_flag)); + + return err; +} + +static int compat_get_qseecom_update_key_userinfo_req( + struct compat_qseecom_update_key_userinfo_req __user *data32, + struct qseecom_update_key_userinfo_req *data) +{ + int err = 0; + compat_uint_t usage; + unsigned char current_hash32; + unsigned char new_hash32; + unsigned int i; + + for (i = 0; i < QSEECOM_HASH_SIZE; i++) { + err |= get_user(current_hash32, &(data32->current_hash32[i])); + memcpy( &data->current_hash32[i], ¤t_hash32, sizeof(current_hash32)); + } + for (i = 0; i < QSEECOM_HASH_SIZE; i++) { + err |= get_user(new_hash32, &(data32->new_hash32[i])); + memcpy( &data->new_hash32[i], &new_hash32, sizeof(new_hash32)); + } + err = get_user(usage, &data32->usage); + memcpy(&data->usage, &usage, sizeof(usage)); + + return err; +} + +static int compat_get_qseecom_save_partition_hash_req( + struct compat_qseecom_save_partition_hash_req __user *data32, + struct qseecom_save_partition_hash_req *data) +{ + int err; + compat_int_t partition_id; + char digest; + unsigned int i; + + err = get_user(partition_id, &data32->partition_id); + memcpy(&data->partition_id, &partition_id, sizeof(partition_id)); + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + err |= get_user(digest, &(data32->digest[i])); + memcpy( &data->digest[i], &digest, sizeof(digest)); + } + return err; +} + +static int compat_get_qseecom_is_es_activated_req( + struct compat_qseecom_is_es_activated_req __user *data32, + struct qseecom_is_es_activated_req *data) +{ + compat_int_t is_activated; + int err; + + err = get_user(is_activated, &data32->is_activated); + memcpy(&data->is_activated, &is_activated, sizeof(is_activated)); + return err; +} + +static int compat_get_qseecom_mdtp_cipher_dip_req( + struct compat_qseecom_mdtp_cipher_dip_req __user *data32, + struct qseecom_mdtp_cipher_dip_req *data) +{ + int err; + compat_int_t in_buf_size; + compat_uptr_t in_buf; + compat_int_t out_buf_size; + compat_uptr_t out_buf; + compat_int_t direction; + + err = get_user(in_buf_size, &data32->in_buf_size); + memcpy(&data->in_buf_size, &in_buf_size, sizeof(in_buf_size)); + err |= get_user(out_buf_size, &data32->out_buf_size); + memcpy(&data->out_buf_size, &out_buf_size, sizeof(out_buf_size)); + err |= get_user(direction, &data32->direction); + memcpy(&data->direction, &direction, sizeof(direction)); + err |= get_user(in_buf, &data32->in_buf); + data->in_buf = NULL; + memcpy(&data->in_buf, &in_buf, sizeof(in_buf)); + err |= get_user(out_buf, &data32->out_buf); + data->out_buf = NULL; + memcpy(&data->out_buf, &out_buf, sizeof(out_buf)); + + return err; +} + +static int compat_get_qseecom_send_modfd_listener_resp( + struct compat_qseecom_send_modfd_listener_resp __user *data32, + struct qseecom_send_modfd_listener_resp *data) +{ + int err; + unsigned int i; + compat_uptr_t resp_buf_ptr; + compat_uint_t resp_len; + compat_long_t fd; + compat_ulong_t cmd_buf_offset; + + err = get_user(resp_buf_ptr, &data32->resp_buf_ptr); + data->resp_buf_ptr = NULL; + memcpy(&data->resp_buf_ptr, &resp_buf_ptr, sizeof(resp_buf_ptr)); + err |= get_user(resp_len, &data32->resp_len); + memcpy(&data->resp_len, &resp_len, sizeof(resp_len)); + for (i = 0; i < MAX_ION_FD; i++) { + err |= get_user(fd, &data32->ifd_data[i].fd); + memcpy(&data->ifd_data[i].fd, &fd, sizeof(fd)); + err |= get_user(cmd_buf_offset, + &data32->ifd_data[i].cmd_buf_offset); + memcpy(&data->ifd_data[i].cmd_buf_offset, &cmd_buf_offset, sizeof(cmd_buf_offset)); + } + return err; +} + + +static int compat_get_qseecom_qteec_req( + struct compat_qseecom_qteec_req __user *data32, + struct qseecom_qteec_req *data) +{ + compat_uptr_t req_ptr; + compat_ulong_t req_len; + compat_uptr_t resp_ptr; + compat_ulong_t resp_len; + int err; + + err = get_user(req_ptr, &data32->req_ptr); + data->req_ptr = NULL; + memcpy(&data->req_ptr, &req_ptr, sizeof(req_ptr)); + err |= get_user(req_len, &data32->req_len); + memcpy(&data->req_len, &req_len, sizeof(req_len)); + err |= get_user(resp_ptr, &data32->resp_ptr); + data->resp_ptr = NULL; + memcpy(&data->resp_ptr, &resp_ptr, sizeof(resp_ptr)); + err |= get_user(resp_len, &data32->resp_len); + memcpy(&data->resp_len, &resp_len, sizeof(resp_len)); + return err; +} + +static int compat_get_qseecom_qteec_modfd_req( + struct compat_qseecom_qteec_modfd_req __user *data32, + struct qseecom_qteec_modfd_req *data) +{ + compat_uptr_t req_ptr; + compat_ulong_t req_len; + compat_uptr_t resp_ptr; + compat_ulong_t resp_len; + compat_long_t fd; + compat_ulong_t cmd_buf_offset; + int err, i; + + err = get_user(req_ptr, &data32->req_ptr); + data->req_ptr = NULL; + memcpy(&data->req_ptr, &req_ptr, sizeof(req_ptr)); + err |= get_user(req_len, &data32->req_len); + memcpy(&data->req_len, &req_len, sizeof(req_len)); + + err |= get_user(resp_ptr, &data32->resp_ptr); + data->resp_ptr = NULL; + memcpy(&data->resp_ptr, &resp_ptr, sizeof(resp_ptr)); + err |= get_user(resp_len, &data32->resp_len); + memcpy(&data->resp_len, &resp_len, sizeof(resp_len)); + + for (i = 0; i < MAX_ION_FD; i++) { + err |= get_user(fd, &data32->ifd_data[i].fd); + memcpy(&data->ifd_data[i].fd, &fd, sizeof(fd)); + err |= get_user(cmd_buf_offset, + &data32->ifd_data[i].cmd_buf_offset); + memcpy(&data->ifd_data[i].cmd_buf_offset, &cmd_buf_offset, sizeof(cmd_buf_offset)); + } + return err; +} + +static int compat_get_int(compat_int_t __user *data32, + int *data) +{ + compat_int_t x; + int err; + + err = get_user(x, data32); + memcpy(&data, &x, sizeof(x)); + return err; +} + +static int compat_put_qseecom_load_img_req( + struct compat_qseecom_load_img_req __user *data32, + struct qseecom_load_img_req *data) +{ + int err; + compat_ulong_t mdt_len; + compat_ulong_t img_len; + compat_long_t ifd_data_fd; + compat_ulong_t app_arch; + compat_int_t app_id; + char img_name; + unsigned int i; + + memcpy(&mdt_len, &data->mdt_len, sizeof(mdt_len)); + err = put_user(mdt_len, &data32->mdt_len); + memcpy(&img_len, &data->img_len, sizeof(img_len)); + err |= put_user(img_len, &data32->img_len); + memcpy(&ifd_data_fd, &data->ifd_data_fd, sizeof(ifd_data_fd)); + err |= put_user(ifd_data_fd, &data32->ifd_data_fd); + for (i = 0; i < MAX_APP_NAME_SIZE; i++) { + memcpy(&img_name, &data->img_name[i], sizeof(img_name)); + err |= put_user(img_name, &data32->img_name[i]); + } + memcpy(&app_arch, &data->app_arch, sizeof(app_arch)); + err |= put_user(app_arch, &data32->app_arch); + memcpy(&app_id, &data->app_id, sizeof(app_id)); + err |= put_user(app_id, &data32->app_id); + return err; +} + +static int compat_put_qseecom_qseos_version_req( + struct compat_qseecom_qseos_version_req __user *data32, + struct qseecom_qseos_version_req *data) +{ + compat_uint_t qseos_version; + int err; + memcpy(&qseos_version, &data->qseos_version, sizeof(qseos_version)); + err = put_user(qseos_version, &data32->qseos_version); + return err; +} + +static int compat_put_qseecom_qseos_app_load_query( + struct compat_qseecom_qseos_app_load_query __user *data32, + struct qseecom_qseos_app_load_query *data) +{ + int err = 0; + unsigned int i; + compat_int_t app_id; + compat_ulong_t app_arch; + char app_name; + + for (i = 0; i < MAX_APP_NAME_SIZE; i++) { + memcpy(&app_name, &data->app_name[i], sizeof(app_name)); + err |= put_user(app_name, &(data32->app_name[i])); + } + memcpy(&app_id, &data->app_id, sizeof(app_id)); + err |= put_user(app_id, &data32->app_id); + memcpy(&app_arch, &data->app_arch, sizeof(app_arch)); + err |= put_user(app_arch, &data32->app_arch); + + return err; +} + +static int compat_put_qseecom_is_es_activated_req( + struct compat_qseecom_is_es_activated_req __user *data32, + struct qseecom_is_es_activated_req *data) +{ + compat_int_t is_activated; + int err; + + memcpy(&is_activated, &data->is_activated, sizeof(is_activated)); + err = put_user(is_activated, &data32->is_activated); + return err; +} + +static unsigned int convert_cmd(unsigned int cmd) +{ + switch (cmd) { + case COMPAT_QSEECOM_IOCTL_REGISTER_LISTENER_REQ: + return QSEECOM_IOCTL_REGISTER_LISTENER_REQ; + case COMPAT_QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ: + return QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ; + case COMPAT_QSEECOM_IOCTL_LOAD_APP_REQ: + return QSEECOM_IOCTL_LOAD_APP_REQ; + case COMPAT_QSEECOM_IOCTL_RECEIVE_REQ: + return QSEECOM_IOCTL_RECEIVE_REQ; + case COMPAT_QSEECOM_IOCTL_SEND_RESP_REQ: + return QSEECOM_IOCTL_SEND_RESP_REQ; + case COMPAT_QSEECOM_IOCTL_UNLOAD_APP_REQ: + return QSEECOM_IOCTL_UNLOAD_APP_REQ; + case COMPAT_QSEECOM_IOCTL_PERF_ENABLE_REQ: + return QSEECOM_IOCTL_PERF_ENABLE_REQ; + case COMPAT_QSEECOM_IOCTL_PERF_DISABLE_REQ: + return QSEECOM_IOCTL_PERF_DISABLE_REQ; + case COMPAT_QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ: + return QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ; + case COMPAT_QSEECOM_IOCTL_SET_BUS_SCALING_REQ: + return QSEECOM_IOCTL_SET_BUS_SCALING_REQ; + case COMPAT_QSEECOM_IOCTL_SEND_CMD_REQ: + return QSEECOM_IOCTL_SEND_CMD_REQ; + case COMPAT_QSEECOM_IOCTL_SEND_MODFD_CMD_REQ: + return QSEECOM_IOCTL_SEND_MODFD_CMD_REQ; + case COMPAT_QSEECOM_IOCTL_SET_MEM_PARAM_REQ: + return QSEECOM_IOCTL_SET_MEM_PARAM_REQ; + case COMPAT_QSEECOM_IOCTL_GET_QSEOS_VERSION_REQ: + return QSEECOM_IOCTL_GET_QSEOS_VERSION_REQ; + case COMPAT_QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ: + return QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ; + case COMPAT_QSEECOM_IOCTL_APP_LOADED_QUERY_REQ: + return QSEECOM_IOCTL_APP_LOADED_QUERY_REQ; + case COMPAT_QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ: + return QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ; + case COMPAT_QSEECOM_IOCTL_CREATE_KEY_REQ: + return QSEECOM_IOCTL_CREATE_KEY_REQ; + case COMPAT_QSEECOM_IOCTL_WIPE_KEY_REQ: + return QSEECOM_IOCTL_WIPE_KEY_REQ; + case COMPAT_QSEECOM_IOCTL_UPDATE_KEY_USER_INFO_REQ: + return QSEECOM_IOCTL_UPDATE_KEY_USER_INFO_REQ; + case COMPAT_QSEECOM_IOCTL_SAVE_PARTITION_HASH_REQ: + return QSEECOM_IOCTL_SAVE_PARTITION_HASH_REQ; + case COMPAT_QSEECOM_IOCTL_IS_ES_ACTIVATED_REQ: + return QSEECOM_IOCTL_IS_ES_ACTIVATED_REQ; + case COMPAT_QSEECOM_IOCTL_SEND_MODFD_RESP: + return QSEECOM_IOCTL_SEND_MODFD_RESP; + case COMPAT_QSEECOM_QTEEC_IOCTL_OPEN_SESSION_REQ: + return QSEECOM_QTEEC_IOCTL_OPEN_SESSION_REQ; + case COMPAT_QSEECOM_QTEEC_IOCTL_CLOSE_SESSION_REQ: + return QSEECOM_QTEEC_IOCTL_CLOSE_SESSION_REQ; + case COMPAT_QSEECOM_QTEEC_IOCTL_INVOKE_MODFD_CMD_REQ: + return QSEECOM_QTEEC_IOCTL_INVOKE_MODFD_CMD_REQ; + case COMPAT_QSEECOM_QTEEC_IOCTL_REQUEST_CANCELLATION_REQ: + return QSEECOM_QTEEC_IOCTL_REQUEST_CANCELLATION_REQ; + case COMPAT_QSEECOM_IOCTL_MDTP_CIPHER_DIP_REQ: + return QSEECOM_IOCTL_MDTP_CIPHER_DIP_REQ; + case COMPAT_QSEECOM_IOCTL_SEND_MODFD_CMD_64_REQ: + return QSEECOM_IOCTL_SEND_MODFD_CMD_64_REQ; + case COMPAT_QSEECOM_IOCTL_SEND_MODFD_RESP_64: + return QSEECOM_IOCTL_SEND_MODFD_RESP_64; + + default: + return cmd; + } +} + +long compat_qseecom_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + long ret; + switch (cmd) { + + case COMPAT_QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ: + case COMPAT_QSEECOM_IOCTL_RECEIVE_REQ: + case COMPAT_QSEECOM_IOCTL_SEND_RESP_REQ: + case COMPAT_QSEECOM_IOCTL_UNLOAD_APP_REQ: + case COMPAT_QSEECOM_IOCTL_PERF_ENABLE_REQ: + case COMPAT_QSEECOM_IOCTL_PERF_DISABLE_REQ: + case COMPAT_QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ: { + return qseecom_ioctl(file, convert_cmd(cmd), 0); + } + break; + case COMPAT_QSEECOM_IOCTL_REGISTER_LISTENER_REQ: { + struct compat_qseecom_register_listener_req __user *data32; + struct qseecom_register_listener_req *data; + int err; + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_register_listener_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_LOAD_APP_REQ: { + struct compat_qseecom_load_img_req __user *data32; + struct qseecom_load_img_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + err = compat_get_qseecom_load_img_req(data32, data); + if (err) + return err; + + ret = qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + err = compat_put_qseecom_load_img_req(data32, data); + return ret ? ret : err; + } + break; + case COMPAT_QSEECOM_IOCTL_SEND_CMD_REQ: { + struct compat_qseecom_send_cmd_req __user *data32; + struct qseecom_send_cmd_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_send_cmd_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_SEND_MODFD_CMD_REQ: + case COMPAT_QSEECOM_IOCTL_SEND_MODFD_CMD_64_REQ: { + struct compat_qseecom_send_modfd_cmd_req __user *data32; + struct qseecom_send_modfd_cmd_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_send_modfd_cmd_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_SET_MEM_PARAM_REQ: { + struct compat_qseecom_set_sb_mem_param_req __user *data32; + struct qseecom_set_sb_mem_param_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_set_sb_mem_param_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_GET_QSEOS_VERSION_REQ: { + struct compat_qseecom_qseos_version_req __user *data32; + struct qseecom_qseos_version_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_qseos_version_req(data32, data); + if (err) + return err; + + ret = qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + err = compat_put_qseecom_qseos_version_req(data32, data); + + return ret ? ret : err; + } + break; + case COMPAT_QSEECOM_IOCTL_SET_BUS_SCALING_REQ: { + compat_int_t __user *data32; + int *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + err = compat_get_int(data32, data); + if (err) + return err; + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ: { + struct compat_qseecom_load_img_req __user *data32; + struct qseecom_load_img_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_load_img_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_APP_LOADED_QUERY_REQ: { + struct compat_qseecom_qseos_app_load_query __user *data32; + struct qseecom_qseos_app_load_query *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_qseos_app_load_query(data32, data); + if (err) + return err; + + ret = qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + err = compat_put_qseecom_qseos_app_load_query(data32, data); + return ret ? ret : err; + } + break; + case COMPAT_QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ: { + struct compat_qseecom_send_svc_cmd_req __user *data32; + struct qseecom_send_svc_cmd_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_send_svc_cmd_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_CREATE_KEY_REQ: { + struct compat_qseecom_create_key_req __user *data32; + struct qseecom_create_key_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_create_key_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_WIPE_KEY_REQ: { + struct compat_qseecom_wipe_key_req __user *data32; + struct qseecom_wipe_key_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_wipe_key_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_UPDATE_KEY_USER_INFO_REQ: { + struct compat_qseecom_update_key_userinfo_req __user *data32; + struct qseecom_update_key_userinfo_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_update_key_userinfo_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_SAVE_PARTITION_HASH_REQ: { + struct compat_qseecom_save_partition_hash_req __user *data32; + struct qseecom_save_partition_hash_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_save_partition_hash_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_IS_ES_ACTIVATED_REQ: { + struct compat_qseecom_is_es_activated_req __user *data32; + struct qseecom_is_es_activated_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_is_es_activated_req(data32, data); + if (err) + return err; + + ret = qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + err = compat_put_qseecom_is_es_activated_req(data32, data); + return ret ? ret : err; + } + break; + case COMPAT_QSEECOM_IOCTL_MDTP_CIPHER_DIP_REQ: { + struct compat_qseecom_mdtp_cipher_dip_req __user *data32; + struct qseecom_mdtp_cipher_dip_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_mdtp_cipher_dip_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_IOCTL_SEND_MODFD_RESP: + case COMPAT_QSEECOM_IOCTL_SEND_MODFD_RESP_64: { + struct compat_qseecom_send_modfd_listener_resp __user *data32; + struct qseecom_send_modfd_listener_resp *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_send_modfd_listener_resp(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_QTEEC_IOCTL_CLOSE_SESSION_REQ: { + struct compat_qseecom_qteec_req __user *data32; + struct qseecom_qteec_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_qteec_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + case COMPAT_QSEECOM_QTEEC_IOCTL_OPEN_SESSION_REQ: + case COMPAT_QSEECOM_QTEEC_IOCTL_INVOKE_MODFD_CMD_REQ: + case COMPAT_QSEECOM_QTEEC_IOCTL_REQUEST_CANCELLATION_REQ: { + struct compat_qseecom_qteec_modfd_req __user *data32; + struct qseecom_qteec_modfd_req *data; + int err; + + data32 = compat_ptr(arg); + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (data == NULL) + return -EFAULT; + + err = compat_get_qseecom_qteec_modfd_req(data32, data); + if (err) + return err; + + return qseecom_ioctl(file, convert_cmd(cmd), + (unsigned long)data); + } + break; + default: + return -ENOIOCTLCMD; + break; + } + return 0; +} diff --git a/qseecom/compat_qseecom.h b/qseecom/compat_qseecom.h new file mode 100644 index 0000000..af16cd8 --- /dev/null +++ b/qseecom/compat_qseecom.h @@ -0,0 +1,341 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2017, 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ +#ifndef _UAPI_COMPAT_QSEECOM_H_ +#define _UAPI_COMPAT_QSEECOM_H_ + +#include <linux/types.h> +#include <linux/ioctl.h> + +#if IS_ENABLED(CONFIG_COMPAT) +#include <linux/compat.h> + +/* + * struct compat_qseecom_register_listener_req - + * for register listener ioctl request + * @listener_id - service id (shared between userspace and QSE) + * @ifd_data_fd - ion handle + * @virt_sb_base - shared buffer base in user space + * @sb_size - shared buffer size + */ +struct compat_qseecom_register_listener_req { + compat_ulong_t listener_id; /* in */ + compat_long_t ifd_data_fd; /* in */ + compat_uptr_t virt_sb_base; /* in */ + compat_ulong_t sb_size; /* in */ +}; + +/* + * struct compat_qseecom_send_cmd_req - for send command ioctl request + * @cmd_req_len - command buffer length + * @cmd_req_buf - command buffer + * @resp_len - response buffer length + * @resp_buf - response buffer + */ +struct compat_qseecom_send_cmd_req { + compat_uptr_t cmd_req_buf; /* in */ + compat_uint_t cmd_req_len; /* in */ + compat_uptr_t resp_buf; /* in/out */ + compat_uint_t resp_len; /* in/out */ +}; + +/* + * struct qseecom_ion_fd_info - ion fd handle data information + * @fd - ion handle to some memory allocated in user space + * @cmd_buf_offset - command buffer offset + */ +struct compat_qseecom_ion_fd_info { + compat_long_t fd; + compat_ulong_t cmd_buf_offset; +}; +/* + * struct qseecom_send_modfd_cmd_req - for send command ioctl request + * @cmd_req_len - command buffer length + * @cmd_req_buf - command buffer + * @resp_len - response buffer length + * @resp_buf - response buffer + * @ifd_data_fd - ion handle to memory allocated in user space + * @cmd_buf_offset - command buffer offset + */ +struct compat_qseecom_send_modfd_cmd_req { + compat_uptr_t cmd_req_buf; /* in */ + compat_uint_t cmd_req_len; /* in */ + compat_uptr_t resp_buf; /* in/out */ + compat_uint_t resp_len; /* in/out */ + struct compat_qseecom_ion_fd_info ifd_data[MAX_ION_FD]; +}; + +/* + * struct compat_qseecom_listener_send_resp_req + * signal to continue the send_cmd req. + * Used as a trigger from HLOS service to notify QSEECOM that it's done with its + * operation and provide the response for QSEECOM can continue the incomplete + * command execution + * @resp_len - Length of the response + * @resp_buf - Response buffer where the response of the cmd should go. + */ +struct compat_qseecom_send_resp_req { + compat_uptr_t resp_buf; /* in */ + compat_uint_t resp_len; /* in */ +}; + +/* + * struct compat_qseecom_load_img_data + * for sending image length information and + * ion file descriptor to the qseecom driver. ion file descriptor is used + * for retrieving the ion file handle and in turn the physical address of + * the image location. + * @mdt_len - Length of the .mdt file in bytes. + * @img_len - Length of the .mdt + .b00 +..+.bxx images files in bytes + * @ion_fd - Ion file descriptor used when allocating memory. + * @img_name - Name of the image. + */ +struct compat_qseecom_load_img_req { + compat_ulong_t mdt_len; /* in */ + compat_ulong_t img_len; /* in */ + compat_long_t ifd_data_fd; /* in */ + char img_name[MAX_APP_NAME_SIZE]; /* in */ + compat_ulong_t app_arch; /* in */ + compat_uint_t app_id; /* out*/ +}; + +struct compat_qseecom_set_sb_mem_param_req { + compat_long_t ifd_data_fd; /* in */ + compat_uptr_t virt_sb_base; /* in */ + compat_ulong_t sb_len; /* in */ +}; + +/* + * struct compat_qseecom_qseos_version_req - get qseos version + * @qseos_version - version number + */ +struct compat_qseecom_qseos_version_req { + compat_uint_t qseos_version; /* in */ +}; + +/* + * struct compat_qseecom_qseos_app_load_query - verify if app is loaded in qsee + * @app_name[MAX_APP_NAME_SIZE]- name of the app. + * @app_id - app id. + */ +struct compat_qseecom_qseos_app_load_query { + char app_name[MAX_APP_NAME_SIZE]; /* in */ + compat_uint_t app_id; /* out */ + compat_ulong_t app_arch; +}; + +struct compat_qseecom_send_svc_cmd_req { + compat_ulong_t cmd_id; + compat_uptr_t cmd_req_buf; /* in */ + compat_uint_t cmd_req_len; /* in */ + compat_uptr_t resp_buf; /* in/out */ + compat_uint_t resp_len; /* in/out */ +}; + +struct compat_qseecom_create_key_req { + unsigned char hash32[QSEECOM_HASH_SIZE]; + enum qseecom_key_management_usage_type usage; +}; + +struct compat_qseecom_wipe_key_req { + enum qseecom_key_management_usage_type usage; + compat_int_t wipe_key_flag; +}; + +struct compat_qseecom_update_key_userinfo_req { + unsigned char current_hash32[QSEECOM_HASH_SIZE]; + unsigned char new_hash32[QSEECOM_HASH_SIZE]; + enum qseecom_key_management_usage_type usage; +}; + +/* + * struct compat_qseecom_save_partition_hash_req + * @partition_id - partition id. + * @hash[SHA256_DIGEST_LENGTH] - sha256 digest. + */ +struct compat_qseecom_save_partition_hash_req { + compat_int_t partition_id; /* in */ + char digest[SHA256_DIGEST_LENGTH]; /* in */ +}; + +/* + * struct compat_qseecom_is_es_activated_req + * @is_activated - 1=true , 0=false + */ +struct compat_qseecom_is_es_activated_req { + compat_int_t is_activated; /* out */ +}; + +/* + * struct compat_qseecom_mdtp_cipher_dip_req + * @in_buf - input buffer + * @in_buf_size - input buffer size + * @out_buf - output buffer + * @out_buf_size - output buffer size + * @direction - 0=encrypt, 1=decrypt + */ +struct compat_qseecom_mdtp_cipher_dip_req { + compat_uptr_t in_buf; + compat_uint_t in_buf_size; + compat_uptr_t out_buf; + compat_uint_t out_buf_size; + compat_uint_t direction; +}; + +/* + * struct qseecom_send_modfd_resp - for send command ioctl request + * @req_len - command buffer length + * @req_buf - command buffer + * @ifd_data_fd - ion handle to memory allocated in user space + * @cmd_buf_offset - command buffer offset + */ +struct compat_qseecom_send_modfd_listener_resp { + compat_uptr_t resp_buf_ptr; /* in */ + compat_uint_t resp_len; /* in */ + struct compat_qseecom_ion_fd_info ifd_data[MAX_ION_FD]; /* in */ +}; + +struct compat_qseecom_qteec_req { + compat_uptr_t req_ptr; + compat_ulong_t req_len; + compat_uptr_t resp_ptr; + compat_ulong_t resp_len; +}; + +struct compat_qseecom_qteec_modfd_req { + compat_uptr_t req_ptr; + compat_ulong_t req_len; + compat_uptr_t resp_ptr; + compat_ulong_t resp_len; + struct compat_qseecom_ion_fd_info ifd_data[MAX_ION_FD]; +}; + +struct compat_qseecom_ce_pipe_entry { + compat_int_t valid; + compat_uint_t ce_num; + compat_uint_t ce_pipe_pair; +}; + +struct compat_qseecom_ce_info_req { + unsigned char handle[MAX_CE_INFO_HANDLE_SIZE]; + compat_uint_t usage; + compat_uint_t unit_num; + compat_uint_t num_ce_pipe_entries; + struct compat_qseecom_ce_pipe_entry + ce_pipe_entry[MAX_CE_PIPE_PAIR_PER_UNIT]; +}; + +struct file; +extern long compat_qseecom_ioctl(struct file *file, + unsigned int cmd, unsigned long arg); + +extern long qseecom_ioctl(struct file *file, + unsigned int cmd, unsigned long arg); + +#define COMPAT_QSEECOM_IOCTL_REGISTER_LISTENER_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 1, struct compat_qseecom_register_listener_req) + +#define COMPAT_QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ \ + _IO(QSEECOM_IOC_MAGIC, 2) + +#define COMPAT_QSEECOM_IOCTL_SEND_CMD_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 3, struct compat_qseecom_send_cmd_req) + +#define COMPAT_QSEECOM_IOCTL_SEND_MODFD_CMD_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 4, struct compat_qseecom_send_modfd_cmd_req) + +#define COMPAT_QSEECOM_IOCTL_RECEIVE_REQ \ + _IO(QSEECOM_IOC_MAGIC, 5) + +#define COMPAT_QSEECOM_IOCTL_SEND_RESP_REQ \ + _IO(QSEECOM_IOC_MAGIC, 6) + +#define COMPAT_QSEECOM_IOCTL_LOAD_APP_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 7, struct compat_qseecom_load_img_req) + +#define COMPAT_QSEECOM_IOCTL_SET_MEM_PARAM_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 8, struct compat_qseecom_set_sb_mem_param_req) + +#define COMPAT_QSEECOM_IOCTL_UNLOAD_APP_REQ \ + _IO(QSEECOM_IOC_MAGIC, 9) + +#define COMPAT_QSEECOM_IOCTL_GET_QSEOS_VERSION_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 10, struct compat_qseecom_qseos_version_req) + +#define COMPAT_QSEECOM_IOCTL_PERF_ENABLE_REQ \ + _IO(QSEECOM_IOC_MAGIC, 11) + +#define COMPAT_QSEECOM_IOCTL_PERF_DISABLE_REQ \ + _IO(QSEECOM_IOC_MAGIC, 12) + +#define COMPAT_QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 13, struct compat_qseecom_load_img_req) + +#define COMPAT_QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ \ + _IO(QSEECOM_IOC_MAGIC, 14) + +#define COMPAT_QSEECOM_IOCTL_APP_LOADED_QUERY_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 15, struct compat_qseecom_qseos_app_load_query) + +#define COMPAT_QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 16, struct compat_qseecom_send_svc_cmd_req) + +#define COMPAT_QSEECOM_IOCTL_CREATE_KEY_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 17, struct compat_qseecom_create_key_req) + +#define COMPAT_QSEECOM_IOCTL_WIPE_KEY_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 18, struct compat_qseecom_wipe_key_req) + +#define COMPAT_QSEECOM_IOCTL_SAVE_PARTITION_HASH_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 19, \ + struct compat_qseecom_save_partition_hash_req) + +#define COMPAT_QSEECOM_IOCTL_IS_ES_ACTIVATED_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 20, struct compat_qseecom_is_es_activated_req) + +#define COMPAT_QSEECOM_IOCTL_SEND_MODFD_RESP \ + _IOWR(QSEECOM_IOC_MAGIC, 21, \ + struct compat_qseecom_send_modfd_listener_resp) + +#define COMPAT_QSEECOM_IOCTL_SET_BUS_SCALING_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 23, int) + +#define COMPAT_QSEECOM_IOCTL_UPDATE_KEY_USER_INFO_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 24, \ + struct compat_qseecom_update_key_userinfo_req) + +#define COMPAT_QSEECOM_QTEEC_IOCTL_OPEN_SESSION_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 30, struct compat_qseecom_qteec_modfd_req) + +#define COMPAT_QSEECOM_QTEEC_IOCTL_CLOSE_SESSION_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 31, struct compat_qseecom_qteec_req) + +#define COMPAT_QSEECOM_QTEEC_IOCTL_INVOKE_MODFD_CMD_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 32, struct compat_qseecom_qteec_modfd_req) + +#define COMPAT_QSEECOM_QTEEC_IOCTL_REQUEST_CANCELLATION_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 33, struct compat_qseecom_qteec_modfd_req) + +#define COMPAT_QSEECOM_IOCTL_MDTP_CIPHER_DIP_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 34, struct qseecom_mdtp_cipher_dip_req) + +#define COMPAT_QSEECOM_IOCTL_SEND_MODFD_CMD_64_REQ \ + _IOWR(QSEECOM_IOC_MAGIC, 35, struct compat_qseecom_send_modfd_cmd_req) + +#define COMPAT_QSEECOM_IOCTL_SEND_MODFD_RESP_64 \ + _IOWR(QSEECOM_IOC_MAGIC, 36, \ + struct compat_qseecom_send_modfd_listener_resp) +#define COMPAT_QSEECOM_IOCTL_GET_CE_PIPE_INFO \ + _IOWR(QSEECOM_IOC_MAGIC, 40, \ + struct compat_qseecom_ce_info_req) +#define COMPAT_QSEECOM_IOCTL_FREE_CE_PIPE_INFO \ + _IOWR(QSEECOM_IOC_MAGIC, 41, \ + struct compat_qseecom_ce_info_req) +#define COMPAT_QSEECOM_IOCTL_QUERY_CE_PIPE_INFO \ + _IOWR(QSEECOM_IOC_MAGIC, 42, \ + struct compat_qseecom_ce_info_req) + +#endif +#endif /* _UAPI_COMPAT_QSEECOM_H_ */ diff --git a/qseecom/qseecom.c b/qseecom/qseecom.c index 9aecbe9..8aac9c8 100644 --- a/qseecom/qseecom.c +++ b/qseecom/qseecom.c @@ -53,6 +53,9 @@ #else #include "misc/qseecom_kernel.h" #endif +#if IS_ENABLED(CONFIG_COMPAT) +#include "compat_qseecom.h" +#endif #define QSEECOM_DEV "qseecom" #define QSEOS_VERSION_14 0x14 @@ -1511,11 +1514,7 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data, struct qseecom_registered_listener_list *new_entry; struct qseecom_registered_listener_list *ptr_svc; - ret = copy_from_user(&rcvd_lstnr, argp, sizeof(rcvd_lstnr)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } + memcpy(&rcvd_lstnr, argp, sizeof(rcvd_lstnr)); if (!access_ok((void __user *)rcvd_lstnr.virt_sb_base, rcvd_lstnr.sb_size)) return -EFAULT; @@ -1926,11 +1925,7 @@ static int qseecom_scale_bus_bandwidth(struct qseecom_dev_handle *data, if (qseecom.no_clock_support) return 0; - ret = copy_from_user(&req_mode, argp, sizeof(req_mode)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } + memcpy(&req_mode, argp, sizeof(req_mode)); if (req_mode > HIGH) { pr_err("Invalid bandwidth mode (%d)\n", req_mode); return -EINVAL; @@ -2008,8 +2003,7 @@ static int qseecom_set_client_mem_param(struct qseecom_dev_handle *data, size_t len; /* Copy the relevant information needed for loading the image */ - if (copy_from_user(&req, (void __user *)argp, sizeof(req))) - return -EFAULT; + memcpy(&req, (void __user *)argp, sizeof(req)); if ((req.ifd_data_fd <= 0) || (req.virt_sb_base == NULL) || (req.sb_len == 0)) { @@ -2757,12 +2751,7 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) bool first_time = false; /* Copy the relevant information needed for loading the image */ - if (copy_from_user(&load_img_req, - (void __user *)argp, - sizeof(struct qseecom_load_img_req))) { - pr_err("copy_from_user failed\n"); - return -EFAULT; - } + memcpy(&load_img_req, (void __user *)argp, sizeof(struct qseecom_load_img_req)); /* Check and load cmnlib */ if (qseecom.qsee_version > QSEEE_VERSION_00) { @@ -2979,18 +2968,8 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp) strlcpy(data->client.app_name, load_img_req.img_name, MAX_APP_NAME_SIZE); load_img_req.app_id = app_id; - if (copy_to_user(argp, &load_img_req, sizeof(load_img_req))) { - pr_err("copy_to_user failed\n"); - ret = -EFAULT; - if (first_time) { - spin_lock_irqsave( - &qseecom.registered_app_list_lock, flags); - list_del(&entry->list); - spin_unlock_irqrestore( - &qseecom.registered_app_list_lock, flags); - kfree_sensitive(entry); - } - } + + memcpy(argp, &load_img_req, sizeof(load_img_req)); loadapp_err: if (dmabuf) { @@ -3446,13 +3425,7 @@ static int qseecom_send_service_cmd(struct qseecom_dev_handle *data, /*struct qseecom_command_scm_resp resp;*/ - if (copy_from_user(&req, - (void __user *)argp, - sizeof(req))) { - pr_err("copy_from_user failed\n"); - return -EFAULT; - } - + memcpy(&req, (void __user *)argp, sizeof(req)); if (__validate_send_service_cmd_inputs(data, &req)) return -EINVAL; @@ -3846,11 +3819,7 @@ static int qseecom_send_cmd(struct qseecom_dev_handle *data, void __user *argp) int ret = 0; struct qseecom_send_cmd_req req; - ret = copy_from_user(&req, argp, sizeof(req)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } + memcpy(&req, argp, sizeof(req)); if (__validate_send_cmd_inputs(data, &req)) return -EINVAL; @@ -4343,11 +4312,7 @@ static int __qseecom_send_modfd_cmd(struct qseecom_dev_handle *data, phys_addr_t pa; u8 *va = NULL; - ret = copy_from_user(&req, argp, sizeof(req)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } + memcpy(&req, argp, sizeof(req)); send_cmd_req.cmd_req_buf = req.cmd_req_buf; send_cmd_req.cmd_req_len = req.cmd_req_len; @@ -5506,11 +5471,7 @@ static int __qseecom_send_modfd_resp(struct qseecom_dev_handle *data, struct qseecom_send_modfd_listener_resp resp; struct qseecom_registered_listener_list *this_lstnr = NULL; - if (copy_from_user(&resp, argp, sizeof(resp))) { - pr_err("copy_from_user failed\n"); - return -EINVAL; - } - + memcpy(&resp, argp, sizeof(resp)); this_lstnr = __qseecom_find_svc(data->listener.id); if (this_lstnr == NULL) return -EINVAL; @@ -5548,15 +5509,9 @@ static int qseecom_get_qseos_version(struct qseecom_dev_handle *data, { struct qseecom_qseos_version_req req; - if (copy_from_user(&req, argp, sizeof(req))) { - pr_err("copy_from_user failed\n"); - return -EINVAL; - } + memcpy(&req, argp, sizeof(req)); req.qseos_version = qseecom.qseos_version; - if (copy_to_user(argp, &req, sizeof(req))) { - pr_err("copy_to_user failed\n"); - return -EINVAL; - } + memcpy(argp, &req, sizeof(req)); return 0; } @@ -5844,12 +5799,7 @@ static int qseecom_load_external_elf(struct qseecom_dev_handle *data, void *va = NULL; /* Copy the relevant information needed for loading the image */ - if (copy_from_user(&load_img_req, - (void __user *)argp, - sizeof(struct qseecom_load_img_req))) { - pr_err("copy_from_user failed\n"); - return -EFAULT; - } + memcpy(&load_img_req, (void __user *)argp, sizeof(struct qseecom_load_img_req)); /* Get the handle of the shared fd */ ret = qseecom_vaddr_map(load_img_req.ifd_data_fd, &pa, &va, @@ -6015,12 +5965,8 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, bool found_app = false; /* Copy the relevant information needed for loading the image */ - if (copy_from_user(&query_req, (void __user *)argp, - sizeof(struct qseecom_qseos_app_load_query))) { - pr_err("copy_from_user failed\n"); - ret = -EFAULT; - goto exit_free; - } + memcpy(&query_req, (void __user *)argp, + sizeof(struct qseecom_qseos_app_load_query)); req.qsee_cmd_id = QSEOS_APP_LOOKUP_COMMAND; query_req.app_name[MAX_APP_NAME_SIZE-1] = '\0'; @@ -6093,11 +6039,7 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data, spin_unlock_irqrestore( &qseecom.registered_app_list_lock, flags); } - if (copy_to_user(argp, &query_req, sizeof(query_req))) { - pr_err("copy_to_user failed\n"); - ret = -EFAULT; - goto exit_free; - } + memcpy(argp, &query_req, sizeof(query_req)); ret = -EEXIST; /* app already loaded */ goto exit_free; } @@ -6499,12 +6441,7 @@ static int qseecom_create_key(struct qseecom_dev_handle *data, struct qseecom_key_select_ireq set_key_ireq; uint32_t entries = 0; - ret = copy_from_user(&create_key_req, argp, sizeof(create_key_req)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } - + memcpy(&create_key_req, argp, sizeof(create_key_req)); if (create_key_req.usage < QSEOS_KM_USAGE_DISK_ENCRYPTION || create_key_req.usage >= QSEOS_KM_USAGE_MAX) { pr_err("unsupported usage %d\n", create_key_req.usage); @@ -6644,11 +6581,7 @@ static int qseecom_wipe_key(struct qseecom_dev_handle *data, struct qseecom_key_select_ireq clear_key_ireq; uint32_t entries = 0; - ret = copy_from_user(&wipe_key_req, argp, sizeof(wipe_key_req)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } + memcpy(&wipe_key_req, argp, sizeof(wipe_key_req)); if (wipe_key_req.usage < QSEOS_KM_USAGE_DISK_ENCRYPTION || wipe_key_req.usage >= QSEOS_KM_USAGE_MAX) { @@ -6753,11 +6686,7 @@ static int qseecom_update_key_user_info(struct qseecom_dev_handle *data, struct qseecom_update_key_userinfo_req update_key_req; struct qseecom_key_userinfo_update_ireq ireq; - ret = copy_from_user(&update_key_req, argp, sizeof(update_key_req)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } + memcpy(&update_key_req, argp, sizeof(update_key_req)); if (update_key_req.usage < QSEOS_KM_USAGE_DISK_ENCRYPTION || update_key_req.usage >= QSEOS_KM_USAGE_MAX) { @@ -6827,12 +6756,7 @@ static int qseecom_is_es_activated(void __user *argp) } req.is_activated = resp.result; - ret = copy_to_user(argp, &req, sizeof(req)); - if (ret) { - pr_err("copy_to_user failed\n"); - return ret; - } - + memcpy(argp, &req, sizeof(req)); return 0; } @@ -6888,11 +6812,7 @@ static int qseecom_mdtp_cipher_dip(void __user *argp) break; } - ret = copy_from_user(&req, argp, sizeof(req)); - if (ret) { - pr_err("copy_from_user failed, ret= %d\n", ret); - break; - } + memcpy(&req, argp, sizeof(req)); if (req.in_buf == NULL || req.out_buf == NULL || req.in_buf_size == 0 || req.in_buf_size > MAX_DIP || @@ -6912,13 +6832,7 @@ static int qseecom_mdtp_cipher_dip(void __user *argp) break; } - ret = copy_from_user(tzbufin, (void __user *)req.in_buf, - req.in_buf_size); - if (ret) { - pr_err("copy_from_user failed, ret=%d\n", ret); - break; - } - + memcpy(tzbufin, (void __user *)req.in_buf, req.in_buf_size); qtee_shmbridge_flush_shm_buf(&shmin); /* Prepare the output buffer in kernel space */ @@ -6956,12 +6870,7 @@ static int qseecom_mdtp_cipher_dip(void __user *argp) /* Copy the output buffer from kernel space to userspace */ qtee_shmbridge_flush_shm_buf(&shmout); - ret = copy_to_user((void __user *)req.out_buf, - tzbufout, req.out_buf_size); - if (ret) { - pr_err("copy_to_user failed, ret=%d\n", ret); - break; - } + memcpy((void __user *)req.out_buf, tzbufout, req.out_buf_size); } while (0); __qseecom_free_tzbuf(&shmin); @@ -7390,12 +7299,7 @@ static int qseecom_qteec_open_session(struct qseecom_dev_handle *data, struct qseecom_qteec_modfd_req req; int ret = 0; - ret = copy_from_user(&req, argp, - sizeof(struct qseecom_qteec_modfd_req)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } + memcpy(&req, argp, sizeof(struct qseecom_qteec_modfd_req)); ret = __qseecom_qteec_issue_cmd(data, (struct qseecom_qteec_req *)&req, QSEOS_TEE_OPEN_SESSION); @@ -7408,11 +7312,7 @@ static int qseecom_qteec_close_session(struct qseecom_dev_handle *data, struct qseecom_qteec_req req; int ret = 0; - ret = copy_from_user(&req, argp, sizeof(struct qseecom_qteec_req)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } + memcpy(&req, argp, sizeof(struct qseecom_qteec_req)); ret = __qseecom_qteec_issue_cmd(data, &req, QSEOS_TEE_CLOSE_SESSION); return ret; } @@ -7436,12 +7336,7 @@ static int qseecom_qteec_invoke_modfd_cmd(struct qseecom_dev_handle *data, void *req_ptr = NULL; void *resp_ptr = NULL; - ret = copy_from_user(&req, argp, - sizeof(struct qseecom_qteec_modfd_req)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } + memcpy(&req, argp, sizeof(struct qseecom_qteec_modfd_req)); ret = __qseecom_qteec_validate_msg(data, (struct qseecom_qteec_req *)(&req)); if (ret) @@ -7575,12 +7470,7 @@ static int qseecom_qteec_request_cancellation(struct qseecom_dev_handle *data, struct qseecom_qteec_modfd_req req; int ret = 0; - ret = copy_from_user(&req, argp, - sizeof(struct qseecom_qteec_modfd_req)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } + memcpy(&req, argp, sizeof(struct qseecom_qteec_modfd_req)); ret = __qseecom_qteec_issue_cmd(data, (struct qseecom_qteec_req *)&req, QSEOS_TEE_REQUEST_CANCELLATION); @@ -8300,11 +8190,7 @@ long qseecom_ioctl(struct file *file, case QSEECOM_IOCTL_SET_ICE_INFO: { struct qseecom_ice_data_t ice_data; - ret = copy_from_user(&ice_data, argp, sizeof(ice_data)); - if (ret) { - pr_err("copy_from_user failed\n"); - return -EFAULT; - } + memcpy(&ice_data, argp, sizeof(ice_data)); qcom_ice_set_fde_flag(ice_data.flag); break; } @@ -8428,6 +8314,9 @@ static int qseecom_release(struct inode *inode, struct file *file) static const struct file_operations qseecom_fops = { .owner = THIS_MODULE, .unlocked_ioctl = qseecom_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = compat_qseecom_ioctl, +#endif .open = qseecom_open, .release = qseecom_release }; @@ -8942,12 +8831,7 @@ static int qseecom_get_ce_info(struct qseecom_dev_handle *data, bool found = false; struct qseecom_ce_pipe_entry *pce_entry; - ret = copy_from_user(pinfo, argp, - sizeof(struct qseecom_ce_info_req)); - if (ret) { - pr_err("copy_from_user failed\n"); - return ret; - } + memcpy(pinfo, argp, sizeof(struct qseecom_ce_info_req)); switch (pinfo->usage) { case QSEOS_KM_USAGE_DISK_ENCRYPTION: @@ -9009,10 +8893,7 @@ static int qseecom_get_ce_info(struct qseecom_dev_handle *data, for (; i < MAX_CE_PIPE_PAIR_PER_UNIT; i++) pinfo->ce_pipe_entry[i].valid = 0; - if (copy_to_user(argp, pinfo, sizeof(struct qseecom_ce_info_req))) { - pr_err("copy_to_user failed\n"); - ret = -EFAULT; - } + memcpy(argp, pinfo, sizeof(struct qseecom_ce_info_req)); return ret; } @@ -9027,10 +8908,7 @@ static int qseecom_free_ce_info(struct qseecom_dev_handle *data, int i; bool found = false; - ret = copy_from_user(pinfo, argp, - sizeof(struct qseecom_ce_info_req)); - if (ret) - return ret; + memcpy(pinfo, argp, sizeof(struct qseecom_ce_info_req)); switch (pinfo->usage) { case QSEOS_KM_USAGE_DISK_ENCRYPTION: @@ -9085,10 +8963,7 @@ static int qseecom_query_ce_info(struct qseecom_dev_handle *data, bool found = false; struct qseecom_ce_pipe_entry *pce_entry; - ret = copy_from_user(pinfo, argp, - sizeof(struct qseecom_ce_info_req)); - if (ret) - return ret; + memcpy(pinfo, argp, sizeof(struct qseecom_ce_info_req)); switch (pinfo->usage) { case QSEOS_KM_USAGE_DISK_ENCRYPTION: @@ -9147,10 +9022,7 @@ static int qseecom_query_ce_info(struct qseecom_dev_handle *data, for (; i < MAX_CE_PIPE_PAIR_PER_UNIT; i++) pinfo->ce_pipe_entry[i].valid = 0; out: - if (copy_to_user(argp, pinfo, sizeof(struct qseecom_ce_info_req))) { - pr_err("copy_to_user failed\n"); - ret = -EFAULT; - } + memcpy(argp, pinfo, sizeof(struct qseecom_ce_info_req)); return ret; } diff --git a/smcinvoke/trace_smcinvoke.h b/smcinvoke/trace_smcinvoke.h index 97a6606..afd1c36 100644 --- a/smcinvoke/trace_smcinvoke.h +++ b/smcinvoke/trace_smcinvoke.h @@ -489,7 +489,7 @@ TRACE_EVENT(smcinvoke_release, #endif /* _TRACE_SMCINVOKE_H */ #undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH ../../../../vendor/qcom/opensource/securemsm-kernel/smcinvoke +#define TRACE_INCLUDE_PATH smcinvoke #undef TRACE_INCLUDE_FILE #define TRACE_INCLUDE_FILE trace_smcinvoke |