[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <4cfa9841-43cd-f3f8-8adb-a5868051b586@mm-sol.com>
Date: Fri, 9 Apr 2021 14:08:33 +0300
From: Stanimir Varbanov <svarbanov@...sol.com>
To: Mauro Carvalho Chehab <mchehab+huawei@...nel.org>
Cc: linuxarm@...wei.com, mauro.chehab@...wei.com,
Andy Gross <agross@...nel.org>,
Bjorn Andersson <bjorn.andersson@...aro.org>,
Mauro Carvalho Chehab <mchehab@...nel.org>,
Stanimir Varbanov <stanimir.varbanov@...aro.org>,
linux-arm-msm@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-media@...r.kernel.org
Subject: Re: [PATCH 3/3] media: venus: don't de-reference NULL pointers at IRQ
time
Hi Mauro,
On 4/8/21 10:40 AM, Mauro Carvalho Chehab wrote:
> Smatch is warning that:
> drivers/media/platform/qcom/venus/hfi_venus.c:1100 venus_isr() warn: variable dereferenced before check 'hdev' (see line 1097)
>
> The logic basically does:
> hdev = to_hfi_priv(core);
>
> with is translated to:
> hdev = core->priv;
>
> If the IRQ code can receive a NULL pointer for hdev, there's
> a bug there, as it will first try to de-reference the pointer,
> and then check if it is null.
>
> After looking at the code, it seems that this indeed can happen:
> Basically, the venus IRQ thread is started with:
> devm_request_threaded_irq()
> So, it will only be freed after the driver unbinds.
>
> In order to prevent the IRQ code to work with freed data,
> the logic at venus_hfi_destroy() sets core->priv to NULL,
> which would make the IRQ code to ignore any pending IRQs.
>
> There is, however a race condition, as core->priv is set
> to NULL only after being freed. So, we need also to move the
> core->priv = NULL to happen earlier.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@...nel.org>
> ---
> drivers/media/platform/qcom/venus/hfi_venus.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
Acked-by: Stanimir Varbanov <stanimir.varbanov@...aro.org>
>
> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
> index cebb20cf371f..ce98c523b3c6 100644
> --- a/drivers/media/platform/qcom/venus/hfi_venus.c
> +++ b/drivers/media/platform/qcom/venus/hfi_venus.c
> @@ -1094,12 +1094,15 @@ static irqreturn_t venus_isr(struct venus_core *core)
> {
> struct venus_hfi_device *hdev = to_hfi_priv(core);
> u32 status;
> - void __iomem *cpu_cs_base = hdev->core->cpu_cs_base;
> - void __iomem *wrapper_base = hdev->core->wrapper_base;
> + void __iomem *cpu_cs_base;
> + void __iomem *wrapper_base;
>
> if (!hdev)
> return IRQ_NONE;
>
> + cpu_cs_base = hdev->core->cpu_cs_base;
> + wrapper_base = hdev->core->wrapper_base;
> +
> status = readl(wrapper_base + WRAPPER_INTR_STATUS);
> if (IS_V6(core)) {
> if (status & WRAPPER_INTR_STATUS_A2H_MASK ||
> @@ -1650,10 +1653,10 @@ void venus_hfi_destroy(struct venus_core *core)
> {
> struct venus_hfi_device *hdev = to_hfi_priv(core);
>
> + core->priv = NULL;
> venus_interface_queues_release(hdev);
> mutex_destroy(&hdev->lock);
> kfree(hdev);
> - core->priv = NULL;
> core->ops = NULL;
> }
>
>
--
regards,
Stan
Powered by blists - more mailing lists