All of lore.kernel.org
 help / color / mirror / Atom feed
From: gubbaven@codeaurora.org
To: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Cc: Marcel Holtmann <marcel@holtmann.org>,
	Johan Hedberg <johan.hedberg@gmail.com>,
	Matthias Kaehlcke <mka@chromium.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Bluez mailing list <linux-bluetooth@vger.kernel.org>,
	robh@kernel.org, hemantg@codeaurora.org,
	linux-arm-msm@vger.kernel.org, bgodavar@codeaurora.org,
	Claire Chang <tientzu@chromium.org>,
	Sean Paul <seanpaul@chromium.org>,
	rjliao@codeaurora.org, Yoni Shavit <yshavit@google.com>
Subject: Re: [PATCH v1] Bluetooth: hci_qca: Fix double free during SSR timeout
Date: Tue, 09 Jun 2020 21:25:15 +0530	[thread overview]
Message-ID: <219ebb83d596c245beed703e102122ab@codeaurora.org> (raw)
In-Reply-To: <CANFp7mX1iKNETqzjdp5z4OrRJBdaGV+f4rOQBtGomYEhsazVfw@mail.gmail.com>

Hi Abhishek,

On 2020-06-05 10:23, Abhishek Pandit-Subedi wrote:
> Hi,
> 
> On Thu, Jun 4, 2020 at 6:59 AM Venkata Lakshmi Narayana Gubba
> <gubbaven@codeaurora.org> wrote:
>> 
>> Due to race conditions between qca_hw_error and qca_controller_memdump
>> during SSR timeout,the same pointer is freed twice. Which results to
>> double free error. Now a lock is acquired while SSR state moved to 
>> timeout.
> suggestion: Change "which results to double free error" to "This
> results in a double free."
> suggestion: Change "while SSR state moved to timeout" to "when SSR
> state is changed to timeout"
> 
[Venkata]:
Sure will update in next patchset.
>> 
>> Signed-off-by: Venkata Lakshmi Narayana Gubba 
>> <gubbaven@codeaurora.org>
>> ---
>>  drivers/bluetooth/hci_qca.c | 19 ++++++++++++++-----
>>  1 file changed, 14 insertions(+), 5 deletions(-)
>> 
>> diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c
>> index 836949d..9110775 100644
>> --- a/drivers/bluetooth/hci_qca.c
>> +++ b/drivers/bluetooth/hci_qca.c
>> @@ -983,8 +983,11 @@ static void qca_controller_memdump(struct 
>> work_struct *work)
>>         while ((skb = skb_dequeue(&qca->rx_memdump_q))) {
>> 
>>                 mutex_lock(&qca->hci_memdump_lock);
>> -               /* Skip processing the received packets if timeout 
>> detected. */
>> -               if (qca->memdump_state == QCA_MEMDUMP_TIMEOUT) {
>> +               /* Skip processing the received packets if timeout 
>> detected
>> +                * or memdump collection completed.
>> +                */
>> +               if (qca->memdump_state == QCA_MEMDUMP_TIMEOUT ||
>> +                   qca->memdump_state == QCA_MEMDUMP_COLLECTED) {
>>                         mutex_unlock(&qca->hci_memdump_lock);
>>                         return;
>>                 }
>> @@ -1485,7 +1488,7 @@ static void qca_hw_error(struct hci_dev *hdev, 
>> u8 code)
>>  {
>>         struct hci_uart *hu = hci_get_drvdata(hdev);
>>         struct qca_data *qca = hu->priv;
>> -       struct qca_memdump_data *qca_memdump = qca->qca_memdump;
>> +       struct qca_memdump_data *qca_memdump = NULL;
>>         char *memdump_buf = NULL;
>> 
>>         set_bit(QCA_HW_ERROR_EVENT, &qca->flags);
>> @@ -1509,9 +1512,10 @@ static void qca_hw_error(struct hci_dev *hdev, 
>> u8 code)
>>                 qca_wait_for_dump_collection(hdev);
>>         }
>> 
>> +       mutex_lock(&qca->hci_memdump_lock);
>>         if (qca->memdump_state != QCA_MEMDUMP_COLLECTED) {
>>                 bt_dev_err(hu->hdev, "clearing allocated memory due to 
>> memdump timeout");
>> -               mutex_lock(&qca->hci_memdump_lock);
>> +               qca_memdump = qca->qca_memdump;
>>                 if (qca_memdump)
>>                         memdump_buf = qca_memdump->memdump_buf_head;
>>                 vfree(memdump_buf);
> 
> This section of code looks a bit unclear because it's only partially
> in an if statement. Suggestion:
>   if (qca->qca_memdump) {
>     vfree(qca->qca_memdump->memdump_buf_head);
>     kfree(qca->qca_memdump);
>     qca->qca_memdump = NULL;
>   }
> 
[Venkata]:
Sure will update in next patchset.
>> @@ -1520,8 +1524,13 @@ static void qca_hw_error(struct hci_dev *hdev, 
>> u8 code)
>>                 qca->memdump_state = QCA_MEMDUMP_TIMEOUT;
>>                 cancel_delayed_work(&qca->ctrl_memdump_timeout);
>>                 skb_queue_purge(&qca->rx_memdump_q);
>> -               mutex_unlock(&qca->hci_memdump_lock);
>> +       }
>> +       mutex_unlock(&qca->hci_memdump_lock);
>> +
>> +       if (qca->memdump_state == QCA_MEMDUMP_TIMEOUT ||
>> +           qca->memdump_state == QCA_MEMDUMP_COLLECTED) {
>>                 cancel_work_sync(&qca->ctrl_memdump_evt);
>> +               skb_queue_purge(&qca->rx_memdump_q);
>>         }
> 
> Earlier in the function, you call qca_wait_for_dump_collection for
> [Idle, Collecting] so the state should be either [Timeout, Collected]
> at this branch. So, you can remove the `cancel_delayed_work` and
> `skb_queue_purge` from above and just leave it only in the bottom
> branch. Currently you're duplicating these calls unnecessarily.
> 
> I don't know if we discussed this in an earlier review but I noticed
> that `qca_wait_for_dump_collection` doesn't actually pay attention to
> the return value of `wait_on_bit_timeout`. I don't have context for
> the order of calls anymore but is there a possibility for that timeout
> to complete before `qca_memdump_timeout` is called? In that case, you
> should probably set the state to timeout in
> `qca_wait_for_dump_collection` as well.
> 
[Venkata]:
I see only skb_queue_purge is getting duplicated and will update in next 
patchset.
But cancel_delayed_work is for qca->ctrl_memdump_timeout and 
cancel_work_sync is for
qca->ctrl_memdump_evt.So these calls are not getting duplicated.

If timeout happens in qca_wait_for_dump_collection, we are setting state 
to timeout
in subsequent if block which is  if (qca->memdump_state != 
QCA_MEMDUMP_COLLECTED).
>> 
>>         clear_bit(QCA_HW_ERROR_EVENT, &qca->flags);
>> --
>> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a 
>> member
>> of Code Aurora Forum, hosted by The Linux Foundation
>> 

Regards,
Lakshmi Narayana.

      reply	other threads:[~2020-06-09 15:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-04 13:57 [PATCH v1] Bluetooth: hci_qca: Fix double free during SSR timeout Venkata Lakshmi Narayana Gubba
2020-06-04 15:47 ` bgodavar
2020-06-05  4:53 ` Abhishek Pandit-Subedi
2020-06-09 15:55   ` gubbaven [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=219ebb83d596c245beed703e102122ab@codeaurora.org \
    --to=gubbaven@codeaurora.org \
    --cc=abhishekpandit@chromium.org \
    --cc=bgodavar@codeaurora.org \
    --cc=hemantg@codeaurora.org \
    --cc=johan.hedberg@gmail.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcel@holtmann.org \
    --cc=mka@chromium.org \
    --cc=rjliao@codeaurora.org \
    --cc=robh@kernel.org \
    --cc=seanpaul@chromium.org \
    --cc=tientzu@chromium.org \
    --cc=yshavit@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.