* [PATCHv6 0/3] media: venus: close() fixes
@ 2024-10-25 16:56 Sergey Senozhatsky
2024-10-25 16:56 ` [PATCHv6 1/3] media: venus: fix enc/dec destruction order Sergey Senozhatsky
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Sergey Senozhatsky @ 2024-10-25 16:56 UTC (permalink / raw)
To: Stanimir Varbanov, Vikash Garodia
Cc: Dikshita Agarwal, Bryan O'Donoghue, linux-media, linux-kernel,
Sergey Senozhatsky
A couple of fixes for venus driver close() handling
(both enc and dec).
v5->v6:
-- added kfree() backtrace to 0002
Sergey Senozhatsky (3):
media: venus: fix enc/dec destruction order
media: venus: sync with threaded IRQ during inst destruction
media: venus: factor out inst destruction routine
drivers/media/platform/qcom/venus/core.c | 25 +++++++++++++++++++
drivers/media/platform/qcom/venus/core.h | 2 ++
drivers/media/platform/qcom/venus/vdec.c | 13 ++--------
drivers/media/platform/qcom/venus/vdec.h | 1 -
.../media/platform/qcom/venus/vdec_ctrls.c | 5 ----
drivers/media/platform/qcom/venus/venc.c | 14 ++---------
drivers/media/platform/qcom/venus/venc.h | 1 -
.../media/platform/qcom/venus/venc_ctrls.c | 5 ----
8 files changed, 31 insertions(+), 35 deletions(-)
--
2.47.0.163.g1226f6d8fa-goog
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv6 1/3] media: venus: fix enc/dec destruction order
2024-10-25 16:56 [PATCHv6 0/3] media: venus: close() fixes Sergey Senozhatsky
@ 2024-10-25 16:56 ` Sergey Senozhatsky
2024-10-25 16:56 ` [PATCHv6 2/3] media: venus: sync with threaded IRQ during inst destruction Sergey Senozhatsky
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Sergey Senozhatsky @ 2024-10-25 16:56 UTC (permalink / raw)
To: Stanimir Varbanov, Vikash Garodia
Cc: Dikshita Agarwal, Bryan O'Donoghue, linux-media, linux-kernel,
Sergey Senozhatsky, Tomasz Figa
We destroy mutex-es too early as they are still taken in
v4l2_fh_exit()->v4l2_event_unsubscribe()->v4l2_ctrl_find().
We should destroy mutex-es right before kfree(). Also
do not vdec_ctrl_deinit() before v4l2_fh_exit().
Fixes: 7472c1c69138 ("[media] media: venus: vdec: add video decoder files")
Suggested-by: Tomasz Figa <tfiga@google.com>
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
drivers/media/platform/qcom/venus/vdec.c | 7 ++++---
drivers/media/platform/qcom/venus/venc.c | 6 +++---
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index 6252a6b3d4ba..0013c4704f03 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -1752,13 +1752,14 @@ static int vdec_close(struct file *file)
cancel_work_sync(&inst->delayed_process_work);
v4l2_m2m_ctx_release(inst->m2m_ctx);
v4l2_m2m_release(inst->m2m_dev);
- vdec_ctrl_deinit(inst);
ida_destroy(&inst->dpb_ids);
hfi_session_destroy(inst);
- mutex_destroy(&inst->lock);
- mutex_destroy(&inst->ctx_q_lock);
v4l2_fh_del(&inst->fh);
v4l2_fh_exit(&inst->fh);
+ vdec_ctrl_deinit(inst);
+
+ mutex_destroy(&inst->lock);
+ mutex_destroy(&inst->ctx_q_lock);
vdec_pm_put(inst, false);
diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
index 322a7737e2c7..6a26a6592424 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -1519,14 +1519,14 @@ static int venc_close(struct file *file)
v4l2_m2m_ctx_release(inst->m2m_ctx);
v4l2_m2m_release(inst->m2m_dev);
- venc_ctrl_deinit(inst);
hfi_session_destroy(inst);
- mutex_destroy(&inst->lock);
- mutex_destroy(&inst->ctx_q_lock);
v4l2_fh_del(&inst->fh);
v4l2_fh_exit(&inst->fh);
+ venc_ctrl_deinit(inst);
inst->enc_state = VENUS_ENC_STATE_DEINIT;
+ mutex_destroy(&inst->lock);
+ mutex_destroy(&inst->ctx_q_lock);
venc_pm_put(inst, false);
--
2.47.0.163.g1226f6d8fa-goog
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCHv6 2/3] media: venus: sync with threaded IRQ during inst destruction
2024-10-25 16:56 [PATCHv6 0/3] media: venus: close() fixes Sergey Senozhatsky
2024-10-25 16:56 ` [PATCHv6 1/3] media: venus: fix enc/dec destruction order Sergey Senozhatsky
@ 2024-10-25 16:56 ` Sergey Senozhatsky
2024-12-04 6:31 ` Sergey Senozhatsky
2024-10-25 16:56 ` [PATCHv6 3/3] media: venus: factor out inst destruction routine Sergey Senozhatsky
` (2 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Sergey Senozhatsky @ 2024-10-25 16:56 UTC (permalink / raw)
To: Stanimir Varbanov, Vikash Garodia
Cc: Dikshita Agarwal, Bryan O'Donoghue, linux-media, linux-kernel,
Sergey Senozhatsky
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
Freed by task 20291:
kasan_set_track+0x4c/0x80
kasan_save_free_info+0x3c/0x60
____kasan_slab_free+0x124/0x1a0
__kasan_slab_free+0x18/0x28
__kmem_cache_free+0x134/0x300
kfree+0xc8/0x1a8
v4l2_m2m_ctx_release+0x44/0x60
venc_close+0x78/0x130 [venus_enc]
v4l2_release+0x20c/0x2f8
__fput+0x328/0x7f0
____fput+0x2c/0x48
task_work_run+0x1e0/0x280
get_signal+0xfb8/0x1190
do_notify_resume+0x34c/0x16a8
el0_svc+0x9c/0xe8
el0t_64_sync_handler+0x48/0x120
el0t_64_sync+0x1a8/0x1b0
Rearrange inst destruction. First remove the inst from the
core->instances list, second synchronize IRQ/IRQ-thread to
make sure that nothing else would see the inst while we take
it down.
Fixes: 7472c1c69138 ("[media] media: venus: vdec: add video decoder files")
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.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);
--
2.47.0.163.g1226f6d8fa-goog
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCHv6 3/3] media: venus: factor out inst destruction routine
2024-10-25 16:56 [PATCHv6 0/3] media: venus: close() fixes Sergey Senozhatsky
2024-10-25 16:56 ` [PATCHv6 1/3] media: venus: fix enc/dec destruction order Sergey Senozhatsky
2024-10-25 16:56 ` [PATCHv6 2/3] media: venus: sync with threaded IRQ during inst destruction Sergey Senozhatsky
@ 2024-10-25 16:56 ` Sergey Senozhatsky
2024-11-01 3:27 ` [PATCHv6 0/3] media: venus: close() fixes Sergey Senozhatsky
2024-11-05 12:04 ` Stanimir Varbanov
4 siblings, 0 replies; 8+ messages in thread
From: Sergey Senozhatsky @ 2024-10-25 16:56 UTC (permalink / raw)
To: Stanimir Varbanov, Vikash Garodia
Cc: Dikshita Agarwal, Bryan O'Donoghue, linux-media, linux-kernel,
Sergey Senozhatsky
Factor out common instance destruction code into
a common function.
Suggested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
drivers/media/platform/qcom/venus/core.c | 25 +++++++++++++++++++
drivers/media/platform/qcom/venus/core.h | 2 ++
drivers/media/platform/qcom/venus/vdec.c | 24 ++----------------
drivers/media/platform/qcom/venus/vdec.h | 1 -
.../media/platform/qcom/venus/vdec_ctrls.c | 5 ----
drivers/media/platform/qcom/venus/venc.c | 24 ++----------------
drivers/media/platform/qcom/venus/venc.h | 1 -
.../media/platform/qcom/venus/venc_ctrls.c | 5 ----
8 files changed, 31 insertions(+), 56 deletions(-)
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 423deb5e94dc..ee6c2051a0c4 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -19,6 +19,7 @@
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-ctrls.h>
#include <media/v4l2-mem2mem.h>
#include <media/v4l2-ioctl.h>
@@ -502,6 +503,30 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev)
return ret;
}
+void venus_close_common(struct venus_inst *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);
+ v4l2_fh_del(&inst->fh);
+ v4l2_fh_exit(&inst->fh);
+ v4l2_ctrl_handler_free(&inst->ctrl_handler);
+
+ mutex_destroy(&inst->lock);
+ mutex_destroy(&inst->ctx_q_lock);
+}
+EXPORT_SYMBOL_GPL(venus_close_common);
+
static __maybe_unused int venus_runtime_resume(struct device *dev)
{
struct venus_core *core = dev_get_drvdata(dev);
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index 435325432922..7bb36a270e15 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -560,4 +560,6 @@ is_fw_rev_or_older(struct venus_core *core, u32 vmajor, u32 vminor, u32 vrev)
(core)->venus_ver.minor == vminor &&
(core)->venus_ver.rev <= vrev);
}
+
+void venus_close_common(struct venus_inst *inst);
#endif
diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c
index b3192a36f388..cba95dc492f1 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -1737,7 +1737,7 @@ static int vdec_open(struct file *file)
err_session_destroy:
hfi_session_destroy(inst);
err_ctrl_deinit:
- vdec_ctrl_deinit(inst);
+ v4l2_ctrl_handler_free(&inst->ctrl_handler);
err_free:
kfree(inst);
return ret;
@@ -1748,29 +1748,9 @@ static int vdec_close(struct file *file)
struct venus_inst *inst = to_inst(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);
+ venus_close_common(inst);
ida_destroy(&inst->dpb_ids);
- v4l2_fh_del(&inst->fh);
- v4l2_fh_exit(&inst->fh);
- vdec_ctrl_deinit(inst);
-
- mutex_destroy(&inst->lock);
- mutex_destroy(&inst->ctx_q_lock);
-
vdec_pm_put(inst, false);
kfree(inst);
diff --git a/drivers/media/platform/qcom/venus/vdec.h b/drivers/media/platform/qcom/venus/vdec.h
index 6b262d0bf561..0cf981108ff0 100644
--- a/drivers/media/platform/qcom/venus/vdec.h
+++ b/drivers/media/platform/qcom/venus/vdec.h
@@ -9,6 +9,5 @@
struct venus_inst;
int vdec_ctrl_init(struct venus_inst *inst);
-void vdec_ctrl_deinit(struct venus_inst *inst);
#endif
diff --git a/drivers/media/platform/qcom/venus/vdec_ctrls.c b/drivers/media/platform/qcom/venus/vdec_ctrls.c
index 7e0f29bf7fae..36ed955b0419 100644
--- a/drivers/media/platform/qcom/venus/vdec_ctrls.c
+++ b/drivers/media/platform/qcom/venus/vdec_ctrls.c
@@ -187,8 +187,3 @@ int vdec_ctrl_init(struct venus_inst *inst)
return 0;
}
-
-void vdec_ctrl_deinit(struct venus_inst *inst)
-{
- v4l2_ctrl_handler_free(&inst->ctrl_handler);
-}
diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
index 36981ce448f5..b9940da73772 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -1505,7 +1505,7 @@ static int venc_open(struct file *file)
err_session_destroy:
hfi_session_destroy(inst);
err_ctrl_deinit:
- venc_ctrl_deinit(inst);
+ v4l2_ctrl_handler_free(&inst->ctrl_handler);
err_free:
kfree(inst);
return ret;
@@ -1516,28 +1516,8 @@ static int venc_close(struct file *file)
struct venus_inst *inst = to_inst(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);
- v4l2_fh_del(&inst->fh);
- v4l2_fh_exit(&inst->fh);
- venc_ctrl_deinit(inst);
-
+ venus_close_common(inst);
inst->enc_state = VENUS_ENC_STATE_DEINIT;
- mutex_destroy(&inst->lock);
- mutex_destroy(&inst->ctx_q_lock);
-
venc_pm_put(inst, false);
kfree(inst);
diff --git a/drivers/media/platform/qcom/venus/venc.h b/drivers/media/platform/qcom/venus/venc.h
index 4ea37fdcd9b8..719d0f73b14b 100644
--- a/drivers/media/platform/qcom/venus/venc.h
+++ b/drivers/media/platform/qcom/venus/venc.h
@@ -9,6 +9,5 @@
struct venus_inst;
int venc_ctrl_init(struct venus_inst *inst);
-void venc_ctrl_deinit(struct venus_inst *inst);
#endif
diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c b/drivers/media/platform/qcom/venus/venc_ctrls.c
index d9d2a293f3ef..c6d1d3675466 100644
--- a/drivers/media/platform/qcom/venus/venc_ctrls.c
+++ b/drivers/media/platform/qcom/venus/venc_ctrls.c
@@ -635,8 +635,3 @@ int venc_ctrl_init(struct venus_inst *inst)
v4l2_ctrl_handler_free(&inst->ctrl_handler);
return ret;
}
-
-void venc_ctrl_deinit(struct venus_inst *inst)
-{
- v4l2_ctrl_handler_free(&inst->ctrl_handler);
-}
--
2.47.0.163.g1226f6d8fa-goog
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCHv6 0/3] media: venus: close() fixes
2024-10-25 16:56 [PATCHv6 0/3] media: venus: close() fixes Sergey Senozhatsky
` (2 preceding siblings ...)
2024-10-25 16:56 ` [PATCHv6 3/3] media: venus: factor out inst destruction routine Sergey Senozhatsky
@ 2024-11-01 3:27 ` Sergey Senozhatsky
2024-11-05 12:04 ` Stanimir Varbanov
4 siblings, 0 replies; 8+ messages in thread
From: Sergey Senozhatsky @ 2024-11-01 3:27 UTC (permalink / raw)
To: linux-media
Cc: Stanimir Varbanov, Vikash Garodia, Dikshita Agarwal,
Bryan O'Donoghue, linux-kernel, Sergey Senozhatsky
On (24/10/26 01:56), Sergey Senozhatsky wrote:
> A couple of fixes for venus driver close() handling
> (both enc and dec).
>
> v5->v6:
> -- added kfree() backtrace to 0002
linux-media folks, are you fine with the series?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCHv6 0/3] media: venus: close() fixes
2024-10-25 16:56 [PATCHv6 0/3] media: venus: close() fixes Sergey Senozhatsky
` (3 preceding siblings ...)
2024-11-01 3:27 ` [PATCHv6 0/3] media: venus: close() fixes Sergey Senozhatsky
@ 2024-11-05 12:04 ` Stanimir Varbanov
2024-11-05 13:38 ` Sergey Senozhatsky
4 siblings, 1 reply; 8+ messages in thread
From: Stanimir Varbanov @ 2024-11-05 12:04 UTC (permalink / raw)
To: Sergey Senozhatsky, Stanimir Varbanov, Vikash Garodia
Cc: Dikshita Agarwal, Bryan O'Donoghue, linux-media, linux-kernel
Hi Sergey,
Thank you for the patch!
On 10/25/24 19:56, Sergey Senozhatsky wrote:
> A couple of fixes for venus driver close() handling
> (both enc and dec).
>
> v5->v6:
> -- added kfree() backtrace to 0002
>
> Sergey Senozhatsky (3):
> media: venus: fix enc/dec destruction order
> media: venus: sync with threaded IRQ during inst destruction
> media: venus: factor out inst destruction routine
Could you please combine 1/3 and 2/3 commit bodies into 3/3 body and
resend the new 3/3 only. I do not see a reason to apply 1/3 and 2/3.
Also, on what platform this was tested?
~Stan
>
> drivers/media/platform/qcom/venus/core.c | 25 +++++++++++++++++++
> drivers/media/platform/qcom/venus/core.h | 2 ++
> drivers/media/platform/qcom/venus/vdec.c | 13 ++--------
> drivers/media/platform/qcom/venus/vdec.h | 1 -
> .../media/platform/qcom/venus/vdec_ctrls.c | 5 ----
> drivers/media/platform/qcom/venus/venc.c | 14 ++---------
> drivers/media/platform/qcom/venus/venc.h | 1 -
> .../media/platform/qcom/venus/venc_ctrls.c | 5 ----
> 8 files changed, 31 insertions(+), 35 deletions(-)
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCHv6 0/3] media: venus: close() fixes
2024-11-05 12:04 ` Stanimir Varbanov
@ 2024-11-05 13:38 ` Sergey Senozhatsky
0 siblings, 0 replies; 8+ messages in thread
From: Sergey Senozhatsky @ 2024-11-05 13:38 UTC (permalink / raw)
To: Stanimir Varbanov
Cc: Sergey Senozhatsky, Stanimir Varbanov, Vikash Garodia,
Dikshita Agarwal, Bryan O'Donoghue, linux-media, linux-kernel
Hi Stanimir,
On (24/11/05 14:04), Stanimir Varbanov wrote:
> On 10/25/24 19:56, Sergey Senozhatsky wrote:
> > A couple of fixes for venus driver close() handling
> > (both enc and dec).
> >
> > v5->v6:
> > -- added kfree() backtrace to 0002
> >
> > Sergey Senozhatsky (3):
> > media: venus: fix enc/dec destruction order
> > media: venus: sync with threaded IRQ during inst destruction
> > media: venus: factor out inst destruction routine
>
> Could you please combine 1/3 and 2/3 commit bodies into 3/3 body and
> resend the new 3/3 only. I do not see a reason to apply 1/3 and 2/3.
So the reason being is that 1/3 fixes a race condition (stale data
in ->fh) and a lockdep splat (wrong destruction order). 2/3 fixes a
completely different race (IRQ vs close) condition and UAF. And 3/3
is just a refactoring that doesn't fix anything. Are you sure you
want to squash all 3 of them? Because they look slightly independent
to me.
> Also, on what platform this was tested?
I ran CTS on one of the strongbad devices.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCHv6 2/3] media: venus: sync with threaded IRQ during inst destruction
2024-10-25 16:56 ` [PATCHv6 2/3] media: venus: sync with threaded IRQ during inst destruction Sergey Senozhatsky
@ 2024-12-04 6:31 ` Sergey Senozhatsky
0 siblings, 0 replies; 8+ messages in thread
From: Sergey Senozhatsky @ 2024-12-04 6:31 UTC (permalink / raw)
To: Stanimir Varbanov, Bryan O'Donoghue
Cc: Vikash Garodia, Dikshita Agarwal, linux-media, linux-kernel,
Sergey Senozhatsky
On (24/10/26 01:56), Sergey Senozhatsky wrote:
> 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
>
> Freed by task 20291:
> kasan_set_track+0x4c/0x80
> kasan_save_free_info+0x3c/0x60
> ____kasan_slab_free+0x124/0x1a0
> __kasan_slab_free+0x18/0x28
> __kmem_cache_free+0x134/0x300
> kfree+0xc8/0x1a8
> v4l2_m2m_ctx_release+0x44/0x60
> venc_close+0x78/0x130 [venus_enc]
> v4l2_release+0x20c/0x2f8
> __fput+0x328/0x7f0
> ____fput+0x2c/0x48
> task_work_run+0x1e0/0x280
> get_signal+0xfb8/0x1190
> do_notify_resume+0x34c/0x16a8
> el0_svc+0x9c/0xe8
> el0t_64_sync_handler+0x48/0x120
> el0t_64_sync+0x1a8/0x1b0
[..]
> @@ -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);
Sorry about the news, I got a regression report this morning and the reporter
points at this patch as the culprit. It sees that under some circumstances
at close() there are still multiple pending requests, so hfi_session_destroy()
performed as the first step (in order to close race condition with
instance destruction) makes it impossible to finish some of those pending
requests ("no valid instance", which was the whole point).
v4l2_m2m_ctx_release() expects to be called before hfi_session_destroy(),
but this leaves us with half destroyed instance on the instances list.
Not sure what to do about it. Would it be safe (?) to call synchronize_irq()
at the very start and then keep the old destruction order (which looks a
little unsafe) like something below *. Or is there something missing in the
driver and there is a way to make sure we don't have any pending
jobs/requests at close()?
* something below
---
/*
* 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);
/*
* Now wait for jobs to be dequeued. Note this will free m2m ctx.
*/
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);
v4l2_ctrl_handler_free(&inst->ctrl_handler);
mutex_destroy(&inst->lock);
mutex_destroy(&inst->ctx_q_lock);
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-12-04 6:32 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-25 16:56 [PATCHv6 0/3] media: venus: close() fixes Sergey Senozhatsky
2024-10-25 16:56 ` [PATCHv6 1/3] media: venus: fix enc/dec destruction order Sergey Senozhatsky
2024-10-25 16:56 ` [PATCHv6 2/3] media: venus: sync with threaded IRQ during inst destruction Sergey Senozhatsky
2024-12-04 6:31 ` Sergey Senozhatsky
2024-10-25 16:56 ` [PATCHv6 3/3] media: venus: factor out inst destruction routine Sergey Senozhatsky
2024-11-01 3:27 ` [PATCHv6 0/3] media: venus: close() fixes Sergey Senozhatsky
2024-11-05 12:04 ` Stanimir Varbanov
2024-11-05 13:38 ` Sergey Senozhatsky
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).