[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4b96f1f8-e084-4599-abe9-05039bfac569@linaro.org>
Date: Thu, 24 Oct 2024 09:59:29 +0100
From: Bryan O'Donoghue <bryan.odonoghue@...aro.org>
To: Sergey Senozhatsky <senozhatsky@...omium.org>,
Stanimir Varbanov <stanimir.k.varbanov@...il.com>,
Vikash Garodia <quic_vgarodia@...cinc.com>
Cc: linux-media@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCHv2 2/2] media: venus: sync with threaded IRQ during inst
destruction
On 24/10/2024 07:16, Sergey Senozhatsky wrote:
> When destroying an inst we should make sure that we don't race
> against threaded IRQ (or pending IRQ), otherwise we can concurrently
> kfree() inst context and inst itself.
>
> BUG: KASAN: slab-use-after-free in vb2_queue_error+0x80/0x90
> Call trace:
> dump_backtrace+0x1c4/0x1f8
> show_stack+0x38/0x60
> dump_stack_lvl+0x168/0x1f0
> print_report+0x170/0x4c8
> kasan_report+0x94/0xd0
> __asan_report_load2_noabort+0x20/0x30
> vb2_queue_error+0x80/0x90
> venus_helper_vb2_queue_error+0x54/0x78
> venc_event_notify+0xec/0x158
> hfi_event_notify+0x878/0xd20
> hfi_process_msg_packet+0x27c/0x4e0
> venus_isr_thread+0x258/0x6e8
> hfi_isr_thread+0x70/0x90
> venus_isr_thread+0x34/0x50
> irq_thread_fn+0x88/0x130
> irq_thread+0x160/0x2c0
> kthread+0x294/0x328
> ret_from_fork+0x10/0x20
>
> Allocated by task 20291:
> kasan_set_track+0x4c/0x80
> kasan_save_alloc_info+0x28/0x38
> __kasan_kmalloc+0x84/0xa0
> kmalloc_trace+0x7c/0x98
> v4l2_m2m_ctx_init+0x74/0x280
> venc_open+0x444/0x6d0
> v4l2_open+0x19c/0x2a0
> chrdev_open+0x374/0x3f0
> do_dentry_open+0x710/0x10a8
> vfs_open+0x88/0xa8
> path_openat+0x1e6c/0x2700
> do_filp_open+0x1a4/0x2e0
> do_sys_openat2+0xe8/0x508
> do_sys_open+0x15c/0x1a0
> __arm64_sys_openat+0xa8/0xc8
> invoke_syscall+0xdc/0x270
> el0_svc_common+0x1ec/0x250
> do_el0_svc+0x54/0x70
> el0_svc+0x50/0xe8
> el0t_64_sync_handler+0x48/0x120
> el0t_64_sync+0x1a8/0x1b0
>
> Re-arragne inst destruction. First remove the inst from the
> core ->instacnes list, second synchronize IRQ/IRQ-thread to
> make sure that nothing else would see the inst while we take
> it down.
>
> Signed-off-by: Sergey Senozhatsky <senozhatsky@...omium.org>
> ---
> drivers/media/platform/qcom/venus/vdec.c | 12 +++++++++++-
> drivers/media/platform/qcom/venus/venc.c | 12 +++++++++++-
> 2 files changed, 22 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
> index 0013c4704f03..b3192a36f388 100644
> --- a/drivers/media/platform/qcom/venus/vdec.c
> +++ b/drivers/media/platform/qcom/venus/vdec.c
> @@ -1750,10 +1750,20 @@ static int vdec_close(struct file *file)
> vdec_pm_get(inst);
>
> cancel_work_sync(&inst->delayed_process_work);
> + /*
> + * First, remove the inst from the ->instances list, so that
> + * to_instance() will return NULL.
> + */
> + hfi_session_destroy(inst);
> + /*
> + * Second, make sure we don't have IRQ/IRQ-thread currently running
> + * or pending execution, which would race with the inst destruction.
> + */
> + synchronize_irq(inst->core->irq);
> +
> v4l2_m2m_ctx_release(inst->m2m_ctx);
> v4l2_m2m_release(inst->m2m_dev);
> ida_destroy(&inst->dpb_ids);
> - hfi_session_destroy(inst);
> v4l2_fh_del(&inst->fh);
> v4l2_fh_exit(&inst->fh);
> vdec_ctrl_deinit(inst);
> diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
> index 6a26a6592424..36981ce448f5 100644
> --- a/drivers/media/platform/qcom/venus/venc.c
> +++ b/drivers/media/platform/qcom/venus/venc.c
> @@ -1517,9 +1517,19 @@ static int venc_close(struct file *file)
>
> venc_pm_get(inst);
>
> + /*
> + * First, remove the inst from the ->instances list, so that
> + * to_instance() will return NULL.
> + */
> + hfi_session_destroy(inst);
> + /*
> + * Second, make sure we don't have IRQ/IRQ-thread currently running
> + * or pending execution, which would race with the inst destruction.
> + */
> + synchronize_irq(inst->core->irq);
> +
> v4l2_m2m_ctx_release(inst->m2m_ctx);
> v4l2_m2m_release(inst->m2m_dev);
> - hfi_session_destroy(inst);
> v4l2_fh_del(&inst->fh);
> v4l2_fh_exit(&inst->fh);
> venc_ctrl_deinit(inst);
This needs a Fixes: tag too.
It also occurs to me that most of the close() operation code is shared
between venc_close() and vdec_close() a welcome patch for V3 would be to
functionally decompose the common code to a shared location.
So that would be your two Fixes: first and then a reduction patch for a
total of three.
Anyway with the Fixes applied
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@...aro.org>
---
bod
Powered by blists - more mailing lists