soc: qcom: qmi_interface: Abort pending transaction

In some cases like SSR, qmi clients are releasing handles without
considering the waiting transactions which results in use after free
of qmi handles after the transaction wait time completes.

Abort the pending transaction during qmi_handle_release to avoid the
use after free.

CRs-Fixed: 2328443
Change-Id: I59e19222b2b9a8ace3d37b4a70ea891ff88db07e
Signed-off-by: Arun Kumar Neelakantam <aneela@codeaurora.org>
This commit is contained in:
Arun Kumar Neelakantam 2018-10-24 15:26:40 +05:30 • committed by Gerrit - the friendly Code Review server
commit 2de05ba6fb

View file

@ -347,6 +347,9 @@ int qmi_txn_wait(struct qmi_txn *txn, unsigned long timeout)
ret = wait_for_completion_timeout(&txn->completion, timeout);
if (txn->result == -ENETRESET)
return txn->result;
mutex_lock(&qmi->txn_lock);
mutex_lock(&txn->lock);
idr_remove(&qmi->txns, txn->id);
@ -685,6 +688,8 @@ void qmi_handle_release(struct qmi_handle *qmi)
{
struct socket *sock = qmi->sock;
struct qmi_service *svc, *tmp;
struct qmi_txn *txn;
int txn_id;
sock->sk->sk_user_data = NULL;
cancel_work_sync(&qmi->work);
@ -698,6 +703,12 @@ void qmi_handle_release(struct qmi_handle *qmi)
destroy_workqueue(qmi->wq);
mutex_lock(&qmi->txn_lock);
idr_for_each_entry(&qmi->txns, txn, txn_id) {
txn->result = -ENETRESET;
complete(&txn->completion);
}
mutex_unlock(&qmi->txn_lock);
idr_destroy(&qmi->txns);
kfree(qmi->recv_buf);