Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87dcf0e8 authored by Zhen Kong's avatar Zhen Kong
Browse files

qseecom: fix listener_access_lock and unregister issues



When __qseecom_reentrancy_process_incomplete_cmd() calls
__qseecom_process_reentrancy_blocked_on_listener(), it should
first release listener_access_lock, as both of them will take
this mutex inside. Besides, when qseecom processes a pending
listener unregister, it should make sure qseecom_release() is
already called on this listener to avoid free this listener's
private data, which will be used by qseecom_release.

Change-Id: I9dd1937e57f9eaf9d440c13244c66ef9f6771671
Signed-off-by: default avatarZhen Kong <zkong@codeaurora.org>
parent 03e6dc12
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
/*
 * QTI Secure Execution Environment Communicator (QSEECOM) driver
 *
 * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -327,6 +327,7 @@ struct qseecom_client_handle {
struct qseecom_listener_handle {
	u32               id;
	bool              unregister_pending;
	bool              release_called;
};

static struct qseecom_control qseecom;
@@ -1333,6 +1334,9 @@ static void __qseecom_processing_pending_lsnr_unregister(void)
		if (entry && entry->data) {
			pr_debug("process pending unregister %d\n",
					entry->data->listener.id);
			/* don't process if qseecom_release is not called*/
			if (!entry->data->listener.release_called)
				break;
			ptr_svc = __qseecom_find_svc(
						entry->data->listener.id);
			if (ptr_svc) {
@@ -2183,8 +2187,10 @@ static int __qseecom_reentrancy_process_incomplete_cmd(
				ret = -EINVAL;
				goto exit;
			}
			mutex_unlock(&listener_access_lock);
			ret = __qseecom_process_reentrancy_blocked_on_listener(
					resp, NULL, data);
			mutex_lock(&listener_access_lock);
			if (ret) {
				pr_err("failed to process App(%d) %s blocked on listener %d\n",
					data->client.app_id,
@@ -7773,6 +7779,7 @@ static int qseecom_release(struct inode *inode, struct file *file)
			free_private_data = false;
			mutex_lock(&listener_access_lock);
			ret = qseecom_unregister_listener(data);
			data->listener.release_called = true;
			mutex_unlock(&listener_access_lock);
			break;
		case QSEECOM_CLIENT_APP: