qseecom: processing invalid listener request
If the requested listener id is not valid, then its service entry
and whitelist table don't exist, so change to use legacy listener
response cmd without whitelist support in this case.
Change-Id: If23b659242b7e447d67abff14ed9cdd03d928cd0
Signed-off-by: Zhen Kong <zkong@codeaurora.org>
(cherry picked from commit e57ea0299b2acbaa8e291b8928b1c7353512337f)
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index b6dcd0b..9a77917 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1649,8 +1649,9 @@
int rc = 0;
uint32_t lstnr;
unsigned long flags;
- struct qseecom_client_listener_data_irsp send_data_rsp;
- struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit;
+ struct qseecom_client_listener_data_irsp send_data_rsp = {0};
+ struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit
+ = {0};
struct qseecom_registered_listener_list *ptr_svc = NULL;
sigset_t new_sigset;
sigset_t old_sigset;
@@ -1748,32 +1749,38 @@
}
err_resp:
qseecom.send_resp_flag = 0;
- ptr_svc->send_resp_flag = 0;
- table = ptr_svc->sglistinfo_ptr;
+ if (ptr_svc) {
+ ptr_svc->send_resp_flag = 0;
+ table = ptr_svc->sglistinfo_ptr;
+ }
if (qseecom.qsee_version < QSEE_VERSION_40) {
send_data_rsp.listener_id = lstnr;
send_data_rsp.status = status;
- send_data_rsp.sglistinfo_ptr =
- (uint32_t)virt_to_phys(table);
- send_data_rsp.sglistinfo_len =
- SGLISTINFO_TABLE_SIZE;
- dmac_flush_range((void *)table,
- (void *)table + SGLISTINFO_TABLE_SIZE);
+ if (table) {
+ send_data_rsp.sglistinfo_ptr =
+ (uint32_t)virt_to_phys(table);
+ send_data_rsp.sglistinfo_len =
+ SGLISTINFO_TABLE_SIZE;
+ dmac_flush_range((void *)table,
+ (void *)table + SGLISTINFO_TABLE_SIZE);
+ }
cmd_buf = (void *)&send_data_rsp;
cmd_len = sizeof(send_data_rsp);
} else {
send_data_rsp_64bit.listener_id = lstnr;
send_data_rsp_64bit.status = status;
- send_data_rsp_64bit.sglistinfo_ptr =
- virt_to_phys(table);
- send_data_rsp_64bit.sglistinfo_len =
- SGLISTINFO_TABLE_SIZE;
- dmac_flush_range((void *)table,
- (void *)table + SGLISTINFO_TABLE_SIZE);
+ if (table) {
+ send_data_rsp_64bit.sglistinfo_ptr =
+ virt_to_phys(table);
+ send_data_rsp_64bit.sglistinfo_len =
+ SGLISTINFO_TABLE_SIZE;
+ dmac_flush_range((void *)table,
+ (void *)table + SGLISTINFO_TABLE_SIZE);
+ }
cmd_buf = (void *)&send_data_rsp_64bit;
cmd_len = sizeof(send_data_rsp_64bit);
}
- if (qseecom.whitelist_support == false)
+ if (qseecom.whitelist_support == false || table == NULL)
*(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND;
else
*(uint32_t *)cmd_buf =
@@ -1797,8 +1804,10 @@
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
cmd_buf, cmd_len, resp, sizeof(*resp));
- ptr_svc->listener_in_use = false;
- __qseecom_clean_listener_sglistinfo(ptr_svc);
+ if (ptr_svc) {
+ ptr_svc->listener_in_use = false;
+ __qseecom_clean_listener_sglistinfo(ptr_svc);
+ }
if (ret) {
pr_err("scm_call() failed with err: %d (app_id = %d)\n",
ret, data->client.app_id);
@@ -1927,8 +1936,9 @@
int rc = 0;
uint32_t lstnr;
unsigned long flags;
- struct qseecom_client_listener_data_irsp send_data_rsp;
- struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit;
+ struct qseecom_client_listener_data_irsp send_data_rsp = {0};
+ struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit
+ = {0};
struct qseecom_registered_listener_list *ptr_svc = NULL;
sigset_t new_sigset;
sigset_t old_sigset;
@@ -2019,30 +2029,36 @@
status = QSEOS_RESULT_SUCCESS;
}
err_resp:
- table = ptr_svc->sglistinfo_ptr;
+ if (ptr_svc)
+ table = ptr_svc->sglistinfo_ptr;
if (qseecom.qsee_version < QSEE_VERSION_40) {
send_data_rsp.listener_id = lstnr;
send_data_rsp.status = status;
- send_data_rsp.sglistinfo_ptr =
- (uint32_t)virt_to_phys(table);
- send_data_rsp.sglistinfo_len = SGLISTINFO_TABLE_SIZE;
- dmac_flush_range((void *)table,
- (void *)table + SGLISTINFO_TABLE_SIZE);
+ if (table) {
+ send_data_rsp.sglistinfo_ptr =
+ (uint32_t)virt_to_phys(table);
+ send_data_rsp.sglistinfo_len =
+ SGLISTINFO_TABLE_SIZE;
+ dmac_flush_range((void *)table,
+ (void *)table + SGLISTINFO_TABLE_SIZE);
+ }
cmd_buf = (void *)&send_data_rsp;
cmd_len = sizeof(send_data_rsp);
} else {
send_data_rsp_64bit.listener_id = lstnr;
send_data_rsp_64bit.status = status;
- send_data_rsp_64bit.sglistinfo_ptr =
- virt_to_phys(table);
- send_data_rsp_64bit.sglistinfo_len =
- SGLISTINFO_TABLE_SIZE;
- dmac_flush_range((void *)table,
- (void *)table + SGLISTINFO_TABLE_SIZE);
+ if (table) {
+ send_data_rsp_64bit.sglistinfo_ptr =
+ virt_to_phys(table);
+ send_data_rsp_64bit.sglistinfo_len =
+ SGLISTINFO_TABLE_SIZE;
+ dmac_flush_range((void *)table,
+ (void *)table + SGLISTINFO_TABLE_SIZE);
+ }
cmd_buf = (void *)&send_data_rsp_64bit;
cmd_len = sizeof(send_data_rsp_64bit);
}
- if (qseecom.whitelist_support == false)
+ if (qseecom.whitelist_support == false || table == NULL)
*(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND;
else
*(uint32_t *)cmd_buf =
@@ -2065,9 +2081,11 @@
ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
cmd_buf, cmd_len, resp, sizeof(*resp));
- ptr_svc->listener_in_use = false;
- __qseecom_clean_listener_sglistinfo(ptr_svc);
- wake_up_interruptible(&ptr_svc->listener_block_app_wq);
+ if (ptr_svc) {
+ ptr_svc->listener_in_use = false;
+ __qseecom_clean_listener_sglistinfo(ptr_svc);
+ wake_up_interruptible(&ptr_svc->listener_block_app_wq);
+ }
if (ret) {
pr_err("scm_call() failed with err: %d (app_id = %d)\n",
@@ -2610,6 +2628,7 @@
}
}
+unload_exit:
if (found_app) {
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags1);
if (app_crash) {
@@ -2632,7 +2651,6 @@
spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
flags1);
}
-unload_exit:
qseecom_unmap_ion_allocated_memory(data);
data->released = true;
return ret;