mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-21 20:04:01 +00:00
soc: qcom: qmi: Fix wait event in handle destroy
If there is a packet in flight during ssr, send failure and handle destruction can happen simultaneously. Although, the handle is freed only after the transactions lists are empty, the list check and wakeup happen without any locks held. This may lead to a free after use crash when wakeup is triggered after handle is freed. Invoke wakeup and list check with appropriate lock being held. CRs-Fixed: 899087 Change-Id: I38306cfe12e0c7ffb1f54b091a23cecb487ae9a0 Signed-off-by: Atish Kumar Patra <apatra@codeaurora.org>
This commit is contained in:
parent
e9a497530e
commit
7bae1e4145
1 changed files with 14 additions and 4 deletions
|
@ -828,6 +828,8 @@ static void clean_txn_info(struct qmi_handle *handle)
|
|||
|
||||
int qmi_handle_destroy(struct qmi_handle *handle)
|
||||
{
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
if (!handle)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -843,10 +845,18 @@ int qmi_handle_destroy(struct qmi_handle *handle)
|
|||
mutex_unlock(&handle->handle_lock);
|
||||
flush_workqueue(handle->handle_wq);
|
||||
destroy_workqueue(handle->handle_wq);
|
||||
wait_event(handle->reset_waitq,
|
||||
(list_empty(&handle->txn_list) &&
|
||||
list_empty(&handle->pending_txn_list)));
|
||||
|
||||
mutex_lock(&handle->handle_lock);
|
||||
while (!list_empty(&handle->txn_list) ||
|
||||
!list_empty(&handle->pending_txn_list)) {
|
||||
prepare_to_wait(&handle->reset_waitq, &wait,
|
||||
TASK_UNINTERRUPTIBLE);
|
||||
mutex_unlock(&handle->handle_lock);
|
||||
schedule();
|
||||
mutex_lock(&handle->handle_lock);
|
||||
finish_wait(&handle->reset_waitq, &wait);
|
||||
}
|
||||
mutex_unlock(&handle->handle_lock);
|
||||
kfree(handle->dest_info);
|
||||
kfree(handle);
|
||||
return 0;
|
||||
|
@ -1052,8 +1062,8 @@ int qmi_send_req_wait(struct qmi_handle *handle,
|
|||
send_req_wait_err:
|
||||
list_del(&txn_handle->list);
|
||||
kfree(txn_handle);
|
||||
mutex_unlock(&handle->handle_lock);
|
||||
wake_up(&handle->reset_waitq);
|
||||
mutex_unlock(&handle->handle_lock);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(qmi_send_req_wait);
|
||||
|
|
Loading…
Reference in a new issue