Переглянути джерело

securemsm-kernel:qseecom: Fix possible race condition

Fix possible race condition in data->type value in case of multithreaded
listener or app IOCTLs.

For example, below could cause inconsistent data->type value while
racing belows IOCTLs

Thread1 with QSEECOM_IOCTL_REGISTER_LISTENER_REQ
Thread2 with QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ.

Change-Id: Id4f0ffcbff70bfbf13423f9f080fbaf51759ad82
Signed-off-by: Nishant Pandey <[email protected]>
Signed-off-by: Divisha Bisht <[email protected]>
Divisha Bisht 6 місяців тому
батько
коміт
95bbe68e9c
1 змінених файлів з 59 додано та 25 видалено
  1. 59 25
      qseecom/qseecom.c

+ 59 - 25
qseecom/qseecom.c

@@ -7668,14 +7668,15 @@ long qseecom_ioctl(struct file *file,
 
 
 	switch (cmd) {
 	switch (cmd) {
 	case QSEECOM_IOCTL_REGISTER_LISTENER_REQ: {
 	case QSEECOM_IOCTL_REGISTER_LISTENER_REQ: {
+		mutex_lock(&listener_access_lock);
 		if (data->type != QSEECOM_GENERIC) {
 		if (data->type != QSEECOM_GENERIC) {
 			pr_err("reg lstnr req: invalid handle (%d)\n",
 			pr_err("reg lstnr req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&listener_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		pr_debug("ioctl register_listener_req()\n");
 		pr_debug("ioctl register_listener_req()\n");
-		mutex_lock(&listener_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		data->type = QSEECOM_LISTENER_SERVICE;
 		data->type = QSEECOM_LISTENER_SERVICE;
 		ret = qseecom_register_listener(data, argp);
 		ret = qseecom_register_listener(data, argp);
@@ -7687,15 +7688,16 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ: {
 	case QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ: {
+		mutex_lock(&listener_access_lock);
 		if ((data->listener.id == 0) ||
 		if ((data->listener.id == 0) ||
 			(data->type != QSEECOM_LISTENER_SERVICE)) {
 			(data->type != QSEECOM_LISTENER_SERVICE)) {
 			pr_err("unreg lstnr req: invalid handle (%d) lid(%d)\n",
 			pr_err("unreg lstnr req: invalid handle (%d) lid(%d)\n",
 						data->type, data->listener.id);
 						data->type, data->listener.id);
+			mutex_unlock(&listener_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		pr_debug("ioctl unregister_listener_req()\n");
 		pr_debug("ioctl unregister_listener_req()\n");
-		mutex_lock(&listener_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_unregister_listener(data);
 		ret = qseecom_unregister_listener(data);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -7706,15 +7708,16 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_SEND_CMD_REQ: {
 	case QSEECOM_IOCTL_SEND_CMD_REQ: {
+		/* Only one client allowed here at a time */
+		mutex_lock(&app_access_lock);
 		if ((data->client.app_id == 0) ||
 		if ((data->client.app_id == 0) ||
 			(data->type != QSEECOM_CLIENT_APP)) {
 			(data->type != QSEECOM_CLIENT_APP)) {
 			pr_err("send cmd req: invalid handle (%d) app_id(%d)\n",
 			pr_err("send cmd req: invalid handle (%d) app_id(%d)\n",
 					data->type, data->client.app_id);
 					data->type, data->client.app_id);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
-		/* Only one client allowed here at a time */
-		mutex_lock(&app_access_lock);
 		if (qseecom.support_bus_scaling) {
 		if (qseecom.support_bus_scaling) {
 			/* register bus bw in case the client doesn't do it */
 			/* register bus bw in case the client doesn't do it */
 			if (!data->mode) {
 			if (!data->mode) {
@@ -7768,15 +7771,16 @@ long qseecom_ioctl(struct file *file,
 	}
 	}
 	case QSEECOM_IOCTL_SEND_MODFD_CMD_REQ:
 	case QSEECOM_IOCTL_SEND_MODFD_CMD_REQ:
 	case QSEECOM_IOCTL_SEND_MODFD_CMD_64_REQ: {
 	case QSEECOM_IOCTL_SEND_MODFD_CMD_64_REQ: {
+		/* Only one client allowed here at a time */
+		mutex_lock(&app_access_lock);
 		if ((data->client.app_id == 0) ||
 		if ((data->client.app_id == 0) ||
 			(data->type != QSEECOM_CLIENT_APP)) {
 			(data->type != QSEECOM_CLIENT_APP)) {
 			pr_err("send mdfd cmd: invalid handle (%d) appid(%d)\n",
 			pr_err("send mdfd cmd: invalid handle (%d) appid(%d)\n",
 					data->type, data->client.app_id);
 					data->type, data->client.app_id);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
-		/* Only one client allowed here at a time */
-		mutex_lock(&app_access_lock);
 		if (qseecom.support_bus_scaling) {
 		if (qseecom.support_bus_scaling) {
 			if (!data->mode) {
 			if (!data->mode) {
 				mutex_lock(&qsee_bw_mutex);
 				mutex_lock(&qsee_bw_mutex);
@@ -7832,10 +7836,12 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_RECEIVE_REQ: {
 	case QSEECOM_IOCTL_RECEIVE_REQ: {
+		mutex_lock(&listener_access_lock);
 		if ((data->listener.id == 0) ||
 		if ((data->listener.id == 0) ||
 			(data->type != QSEECOM_LISTENER_SERVICE)) {
 			(data->type != QSEECOM_LISTENER_SERVICE)) {
 			pr_err("receive req: invalid handle (%d), lid(%d)\n",
 			pr_err("receive req: invalid handle (%d), lid(%d)\n",
 						data->type, data->listener.id);
 						data->type, data->listener.id);
+			mutex_unlock(&listener_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
@@ -7843,19 +7849,21 @@ long qseecom_ioctl(struct file *file,
 		ret = qseecom_receive_req(data);
 		ret = qseecom_receive_req(data);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
 		wake_up_all(&data->abort_wq);
 		wake_up_all(&data->abort_wq);
+		mutex_unlock(&listener_access_lock);
 		if (ret && (ret != -ERESTARTSYS))
 		if (ret && (ret != -ERESTARTSYS))
 			pr_err("failed qseecom_receive_req: %d\n", ret);
 			pr_err("failed qseecom_receive_req: %d\n", ret);
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_SEND_RESP_REQ: {
 	case QSEECOM_IOCTL_SEND_RESP_REQ: {
+		mutex_lock(&listener_access_lock);
 		if ((data->listener.id == 0) ||
 		if ((data->listener.id == 0) ||
 			(data->type != QSEECOM_LISTENER_SERVICE)) {
 			(data->type != QSEECOM_LISTENER_SERVICE)) {
 			pr_err("send resp req: invalid handle (%d), lid(%d)\n",
 			pr_err("send resp req: invalid handle (%d), lid(%d)\n",
 						data->type, data->listener.id);
 						data->type, data->listener.id);
+			mutex_unlock(&listener_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
-		mutex_lock(&listener_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		if (!qseecom.qsee_reentrancy_support)
 		if (!qseecom.qsee_reentrancy_support)
 			ret = qseecom_send_resp();
 			ret = qseecom_send_resp();
@@ -7869,16 +7877,17 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_SET_MEM_PARAM_REQ: {
 	case QSEECOM_IOCTL_SET_MEM_PARAM_REQ: {
+		mutex_lock(&app_access_lock);
 		if ((data->type != QSEECOM_CLIENT_APP) &&
 		if ((data->type != QSEECOM_CLIENT_APP) &&
 			(data->type != QSEECOM_GENERIC) &&
 			(data->type != QSEECOM_GENERIC) &&
 			(data->type != QSEECOM_SECURE_SERVICE)) {
 			(data->type != QSEECOM_SECURE_SERVICE)) {
 			pr_err("set mem param req: invalid handle (%d)\n",
 			pr_err("set mem param req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		pr_debug("SET_MEM_PARAM: qseecom addr = 0x%pK\n", data);
 		pr_debug("SET_MEM_PARAM: qseecom addr = 0x%pK\n", data);
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_set_client_mem_param(data, argp);
 		ret = qseecom_set_client_mem_param(data, argp);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -7889,16 +7898,17 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_LOAD_APP_REQ: {
 	case QSEECOM_IOCTL_LOAD_APP_REQ: {
+		mutex_lock(&app_access_lock);
 		if ((data->type != QSEECOM_GENERIC) &&
 		if ((data->type != QSEECOM_GENERIC) &&
 			(data->type != QSEECOM_CLIENT_APP)) {
 			(data->type != QSEECOM_CLIENT_APP)) {
 			pr_err("load app req: invalid handle (%d)\n",
 			pr_err("load app req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		data->type = QSEECOM_CLIENT_APP;
 		data->type = QSEECOM_CLIENT_APP;
 		pr_debug("LOAD_APP_REQ: qseecom_addr = 0x%pK\n", data);
 		pr_debug("LOAD_APP_REQ: qseecom_addr = 0x%pK\n", data);
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_load_app(data, argp);
 		ret = qseecom_load_app(data, argp);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -7909,15 +7919,16 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_UNLOAD_APP_REQ: {
 	case QSEECOM_IOCTL_UNLOAD_APP_REQ: {
+		mutex_lock(&app_access_lock);
 		if ((data->client.app_id == 0) ||
 		if ((data->client.app_id == 0) ||
 			(data->type != QSEECOM_CLIENT_APP)) {
 			(data->type != QSEECOM_CLIENT_APP)) {
 			pr_err("unload app req:invalid handle(%d) app_id(%d)\n",
 			pr_err("unload app req:invalid handle(%d) app_id(%d)\n",
 					data->type, data->client.app_id);
 					data->type, data->client.app_id);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		pr_debug("UNLOAD_APP: qseecom_addr = 0x%pK\n", data);
 		pr_debug("UNLOAD_APP: qseecom_addr = 0x%pK\n", data);
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_unload_app(data, false);
 		ret = qseecom_unload_app(data, false);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -7936,15 +7947,16 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ: {
 	case QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ: {
+		mutex_lock(&app_access_lock);
 		if (data->type != QSEECOM_GENERIC) {
 		if (data->type != QSEECOM_GENERIC) {
 			pr_err("load ext elf req: invalid client handle (%d)\n",
 			pr_err("load ext elf req: invalid client handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		data->type = QSEECOM_UNAVAILABLE_CLIENT_APP;
 		data->type = QSEECOM_UNAVAILABLE_CLIENT_APP;
 		data->released = true;
 		data->released = true;
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_load_external_elf(data, argp);
 		ret = qseecom_load_external_elf(data, argp);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -7954,14 +7966,15 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ: {
 	case QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ: {
+		mutex_lock(&app_access_lock);
 		if (data->type != QSEECOM_UNAVAILABLE_CLIENT_APP) {
 		if (data->type != QSEECOM_UNAVAILABLE_CLIENT_APP) {
 			pr_err("unload ext elf req: invalid handle (%d)\n",
 			pr_err("unload ext elf req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		data->released = true;
 		data->released = true;
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_unload_external_elf(data);
 		ret = qseecom_unload_external_elf(data);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -7971,15 +7984,16 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_APP_LOADED_QUERY_REQ: {
 	case QSEECOM_IOCTL_APP_LOADED_QUERY_REQ: {
+		mutex_lock(&app_access_lock);
 		if ((data->type != QSEECOM_GENERIC) &&
 		if ((data->type != QSEECOM_GENERIC) &&
 			(data->type != QSEECOM_CLIENT_APP)) {
 			(data->type != QSEECOM_CLIENT_APP)) {
 			pr_err("app loaded query req: invalid handle (%d)\n",
 			pr_err("app loaded query req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		data->type = QSEECOM_CLIENT_APP;
 		data->type = QSEECOM_CLIENT_APP;
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		pr_debug("APP_LOAD_QUERY: qseecom_addr = 0x%pK\n", data);
 		pr_debug("APP_LOAD_QUERY: qseecom_addr = 0x%pK\n", data);
 		ret = qseecom_query_app_loaded(data, argp);
 		ret = qseecom_query_app_loaded(data, argp);
@@ -7988,9 +8002,11 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ: {
 	case QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ: {
+		mutex_lock(&app_access_lock);
 		if (data->type != QSEECOM_GENERIC) {
 		if (data->type != QSEECOM_GENERIC) {
 			pr_err("send cmd svc req: invalid handle (%d)\n",
 			pr_err("send cmd svc req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
@@ -7998,9 +8014,9 @@ long qseecom_ioctl(struct file *file,
 		if (qseecom.qsee_version < QSEE_VERSION_03) {
 		if (qseecom.qsee_version < QSEE_VERSION_03) {
 			pr_err("SEND_CMD_SERVICE_REQ: Invalid qsee ver %u\n",
 			pr_err("SEND_CMD_SERVICE_REQ: Invalid qsee ver %u\n",
 				qseecom.qsee_version);
 				qseecom.qsee_version);
+			mutex_unlock(&app_access_lock);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_send_service_cmd(data, argp);
 		ret = qseecom_send_service_cmd(data, argp);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -8010,19 +8026,21 @@ long qseecom_ioctl(struct file *file,
 	case QSEECOM_IOCTL_CREATE_KEY_REQ: {
 	case QSEECOM_IOCTL_CREATE_KEY_REQ: {
 		if (!(qseecom.support_pfe || qseecom.support_fde))
 		if (!(qseecom.support_pfe || qseecom.support_fde))
 			pr_err("Features requiring key init not supported\n");
 			pr_err("Features requiring key init not supported\n");
+		mutex_lock(&app_access_lock);
 		if (data->type != QSEECOM_GENERIC) {
 		if (data->type != QSEECOM_GENERIC) {
 			pr_err("create key req: invalid handle (%d)\n",
 			pr_err("create key req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		if (qseecom.qsee_version < QSEE_VERSION_05) {
 		if (qseecom.qsee_version < QSEE_VERSION_05) {
 			pr_err("Create Key feature unsupported: qsee ver %u\n",
 			pr_err("Create Key feature unsupported: qsee ver %u\n",
 				qseecom.qsee_version);
 				qseecom.qsee_version);
+			mutex_unlock(&app_access_lock);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 		data->released = true;
 		data->released = true;
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_create_key(data, argp);
 		ret = qseecom_create_key(data, argp);
 		if (ret)
 		if (ret)
@@ -8035,19 +8053,21 @@ long qseecom_ioctl(struct file *file,
 	case QSEECOM_IOCTL_WIPE_KEY_REQ: {
 	case QSEECOM_IOCTL_WIPE_KEY_REQ: {
 		if (!(qseecom.support_pfe || qseecom.support_fde))
 		if (!(qseecom.support_pfe || qseecom.support_fde))
 			pr_err("Features requiring key init not supported\n");
 			pr_err("Features requiring key init not supported\n");
+		mutex_lock(&app_access_lock);
 		if (data->type != QSEECOM_GENERIC) {
 		if (data->type != QSEECOM_GENERIC) {
 			pr_err("wipe key req: invalid handle (%d)\n",
 			pr_err("wipe key req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		if (qseecom.qsee_version < QSEE_VERSION_05) {
 		if (qseecom.qsee_version < QSEE_VERSION_05) {
 			pr_err("Wipe Key feature unsupported in qsee ver %u\n",
 			pr_err("Wipe Key feature unsupported in qsee ver %u\n",
 				qseecom.qsee_version);
 				qseecom.qsee_version);
+			mutex_unlock(&app_access_lock);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 		data->released = true;
 		data->released = true;
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_wipe_key(data, argp);
 		ret = qseecom_wipe_key(data, argp);
 		if (ret)
 		if (ret)
@@ -8059,19 +8079,21 @@ long qseecom_ioctl(struct file *file,
 	case QSEECOM_IOCTL_UPDATE_KEY_USER_INFO_REQ: {
 	case QSEECOM_IOCTL_UPDATE_KEY_USER_INFO_REQ: {
 		if (!(qseecom.support_pfe || qseecom.support_fde))
 		if (!(qseecom.support_pfe || qseecom.support_fde))
 			pr_err("Features requiring key init not supported\n");
 			pr_err("Features requiring key init not supported\n");
+		mutex_lock(&app_access_lock);
 		if (data->type != QSEECOM_GENERIC) {
 		if (data->type != QSEECOM_GENERIC) {
 			pr_err("update key req: invalid handle (%d)\n",
 			pr_err("update key req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		if (qseecom.qsee_version < QSEE_VERSION_05) {
 		if (qseecom.qsee_version < QSEE_VERSION_05) {
 			pr_err("Update Key feature unsupported in qsee ver %u\n",
 			pr_err("Update Key feature unsupported in qsee ver %u\n",
 				qseecom.qsee_version);
 				qseecom.qsee_version);
+			mutex_unlock(&app_access_lock);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 		data->released = true;
 		data->released = true;
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_update_key_user_info(data, argp);
 		ret = qseecom_update_key_user_info(data, argp);
 		if (ret)
 		if (ret)
@@ -8081,14 +8103,15 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_SAVE_PARTITION_HASH_REQ: {
 	case QSEECOM_IOCTL_SAVE_PARTITION_HASH_REQ: {
+		mutex_lock(&app_access_lock);
 		if (data->type != QSEECOM_GENERIC) {
 		if (data->type != QSEECOM_GENERIC) {
 			pr_err("save part hash req: invalid handle (%d)\n",
 			pr_err("save part hash req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		data->released = true;
 		data->released = true;
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_save_partition_hash(argp);
 		ret = qseecom_save_partition_hash(argp);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -8096,14 +8119,15 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_IS_ES_ACTIVATED_REQ: {
 	case QSEECOM_IOCTL_IS_ES_ACTIVATED_REQ: {
+		mutex_lock(&app_access_lock);
 		if (data->type != QSEECOM_GENERIC) {
 		if (data->type != QSEECOM_GENERIC) {
 			pr_err("ES activated req: invalid handle (%d)\n",
 			pr_err("ES activated req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		data->released = true;
 		data->released = true;
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_is_es_activated(argp);
 		ret = qseecom_is_es_activated(argp);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -8111,14 +8135,15 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_IOCTL_MDTP_CIPHER_DIP_REQ: {
 	case QSEECOM_IOCTL_MDTP_CIPHER_DIP_REQ: {
+		mutex_lock(&app_access_lock);
 		if (data->type != QSEECOM_GENERIC) {
 		if (data->type != QSEECOM_GENERIC) {
 			pr_err("MDTP cipher DIP req: invalid handle (%d)\n",
 			pr_err("MDTP cipher DIP req: invalid handle (%d)\n",
 								data->type);
 								data->type);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		data->released = true;
 		data->released = true;
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_mdtp_cipher_dip(argp);
 		ret = qseecom_mdtp_cipher_dip(argp);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -8127,14 +8152,15 @@ long qseecom_ioctl(struct file *file,
 	}
 	}
 	case QSEECOM_IOCTL_SEND_MODFD_RESP:
 	case QSEECOM_IOCTL_SEND_MODFD_RESP:
 	case QSEECOM_IOCTL_SEND_MODFD_RESP_64: {
 	case QSEECOM_IOCTL_SEND_MODFD_RESP_64: {
+		mutex_lock(&listener_access_lock);
 		if ((data->listener.id == 0) ||
 		if ((data->listener.id == 0) ||
 			(data->type != QSEECOM_LISTENER_SERVICE)) {
 			(data->type != QSEECOM_LISTENER_SERVICE)) {
 			pr_err("receive req: invalid handle (%d), lid(%d)\n",
 			pr_err("receive req: invalid handle (%d), lid(%d)\n",
 						data->type, data->listener.id);
 						data->type, data->listener.id);
+			mutex_unlock(&listener_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
-		mutex_lock(&listener_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		if (cmd == QSEECOM_IOCTL_SEND_MODFD_RESP)
 		if (cmd == QSEECOM_IOCTL_SEND_MODFD_RESP)
 			ret = qseecom_send_modfd_resp(data, argp);
 			ret = qseecom_send_modfd_resp(data, argp);
@@ -8149,20 +8175,22 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_QTEEC_IOCTL_OPEN_SESSION_REQ: {
 	case QSEECOM_QTEEC_IOCTL_OPEN_SESSION_REQ: {
+		mutex_lock(&app_access_lock);
 		if ((data->client.app_id == 0) ||
 		if ((data->client.app_id == 0) ||
 			(data->type != QSEECOM_CLIENT_APP)) {
 			(data->type != QSEECOM_CLIENT_APP)) {
 			pr_err("Open session: invalid handle (%d) appid(%d)\n",
 			pr_err("Open session: invalid handle (%d) appid(%d)\n",
 					data->type, data->client.app_id);
 					data->type, data->client.app_id);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		if (qseecom.qsee_version < QSEE_VERSION_40) {
 		if (qseecom.qsee_version < QSEE_VERSION_40) {
 			pr_err("GP feature unsupported: qsee ver %u\n",
 			pr_err("GP feature unsupported: qsee ver %u\n",
 				qseecom.qsee_version);
 				qseecom.qsee_version);
+			mutex_unlock(&app_access_lock);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 		/* Only one client allowed here at a time */
 		/* Only one client allowed here at a time */
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_qteec_open_session(data, argp);
 		ret = qseecom_qteec_open_session(data, argp);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -8174,20 +8202,22 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_QTEEC_IOCTL_CLOSE_SESSION_REQ: {
 	case QSEECOM_QTEEC_IOCTL_CLOSE_SESSION_REQ: {
+		mutex_lock(&app_access_lock);
 		if ((data->client.app_id == 0) ||
 		if ((data->client.app_id == 0) ||
 			(data->type != QSEECOM_CLIENT_APP)) {
 			(data->type != QSEECOM_CLIENT_APP)) {
 			pr_err("Close session: invalid handle (%d) appid(%d)\n",
 			pr_err("Close session: invalid handle (%d) appid(%d)\n",
 					data->type, data->client.app_id);
 					data->type, data->client.app_id);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		if (qseecom.qsee_version < QSEE_VERSION_40) {
 		if (qseecom.qsee_version < QSEE_VERSION_40) {
 			pr_err("GP feature unsupported: qsee ver %u\n",
 			pr_err("GP feature unsupported: qsee ver %u\n",
 				qseecom.qsee_version);
 				qseecom.qsee_version);
+			mutex_unlock(&app_access_lock);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 		/* Only one client allowed here at a time */
 		/* Only one client allowed here at a time */
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_qteec_close_session(data, argp);
 		ret = qseecom_qteec_close_session(data, argp);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -8198,20 +8228,22 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_QTEEC_IOCTL_INVOKE_MODFD_CMD_REQ: {
 	case QSEECOM_QTEEC_IOCTL_INVOKE_MODFD_CMD_REQ: {
+		mutex_lock(&app_access_lock);
 		if ((data->client.app_id == 0) ||
 		if ((data->client.app_id == 0) ||
 			(data->type != QSEECOM_CLIENT_APP)) {
 			(data->type != QSEECOM_CLIENT_APP)) {
 			pr_err("Invoke cmd: invalid handle (%d) appid(%d)\n",
 			pr_err("Invoke cmd: invalid handle (%d) appid(%d)\n",
 					data->type, data->client.app_id);
 					data->type, data->client.app_id);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		if (qseecom.qsee_version < QSEE_VERSION_40) {
 		if (qseecom.qsee_version < QSEE_VERSION_40) {
 			pr_err("GP feature unsupported: qsee ver %u\n",
 			pr_err("GP feature unsupported: qsee ver %u\n",
 				qseecom.qsee_version);
 				qseecom.qsee_version);
+			mutex_unlock(&app_access_lock);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 		/* Only one client allowed here at a time */
 		/* Only one client allowed here at a time */
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_qteec_invoke_modfd_cmd(data, argp);
 		ret = qseecom_qteec_invoke_modfd_cmd(data, argp);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);
@@ -8223,20 +8255,22 @@ long qseecom_ioctl(struct file *file,
 		break;
 		break;
 	}
 	}
 	case QSEECOM_QTEEC_IOCTL_REQUEST_CANCELLATION_REQ: {
 	case QSEECOM_QTEEC_IOCTL_REQUEST_CANCELLATION_REQ: {
+		mutex_lock(&app_access_lock);
 		if ((data->client.app_id == 0) ||
 		if ((data->client.app_id == 0) ||
 			(data->type != QSEECOM_CLIENT_APP)) {
 			(data->type != QSEECOM_CLIENT_APP)) {
 			pr_err("Cancel req: invalid handle (%d) appid(%d)\n",
 			pr_err("Cancel req: invalid handle (%d) appid(%d)\n",
 					data->type, data->client.app_id);
 					data->type, data->client.app_id);
+			mutex_unlock(&app_access_lock);
 			ret = -EINVAL;
 			ret = -EINVAL;
 			break;
 			break;
 		}
 		}
 		if (qseecom.qsee_version < QSEE_VERSION_40) {
 		if (qseecom.qsee_version < QSEE_VERSION_40) {
 			pr_err("GP feature unsupported: qsee ver %u\n",
 			pr_err("GP feature unsupported: qsee ver %u\n",
 				qseecom.qsee_version);
 				qseecom.qsee_version);
+			mutex_unlock(&app_access_lock);
 			return -EINVAL;
 			return -EINVAL;
 		}
 		}
 		/* Only one client allowed here at a time */
 		/* Only one client allowed here at a time */
-		mutex_lock(&app_access_lock);
 		atomic_inc(&data->ioctl_count);
 		atomic_inc(&data->ioctl_count);
 		ret = qseecom_qteec_request_cancellation(data, argp);
 		ret = qseecom_qteec_request_cancellation(data, argp);
 		atomic_dec(&data->ioctl_count);
 		atomic_dec(&data->ioctl_count);