From 92853681866395fd7ed534f4e1de52f3fd47ab2e Mon Sep 17 00:00:00 2001 From: Renjiang Han Date: Mon, 16 Mar 2026 09:03:48 +0530 Subject: [PATCH] video-driver: fix UAF in close/streamoff path Move vb2_queue_deinit() before session close to avoid freeing inst->packet before venus_hfi_stop(). Also add defensive checks before dereferencing dma-buf file pointers and fix a missing put_inst() on stats_work error paths. Change-Id: I205d37a8743bffd6805b99a99981e5313444513d Signed-off-by: Renjiang Han --- driver/vidc/src/msm_vidc.c | 6 ++++++ driver/vidc/src/msm_vidc_driver.c | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/driver/vidc/src/msm_vidc.c b/driver/vidc/src/msm_vidc.c index f3a5bd41..836332cc 100644 --- a/driver/vidc/src/msm_vidc.c +++ b/driver/vidc/src/msm_vidc.c @@ -961,6 +961,12 @@ int msm_vidc_close(struct msm_vidc_inst *inst, struct file *filp) /* print internal buffer memory usage stats */ msm_vidc_print_memory_stats(inst); msm_vidc_print_residency_stats(core); + /* + * vb2_queue_deinit() must happen before session close so that + * venus_hfi_stop() (called from stop_streaming vb2 callback) + * can succeed with a valid inst->packet. + */ + msm_vidc_vb2_queue_deinit(inst); msm_vidc_session_close(inst); msm_vidc_change_state(inst, MSM_VIDC_CLOSE, __func__); inst->sub_state = MSM_VIDC_SUB_STATE_NONE; diff --git a/driver/vidc/src/msm_vidc_driver.c b/driver/vidc/src/msm_vidc_driver.c index 7b6447cc..16eda673 100644 --- a/driver/vidc/src/msm_vidc_driver.c +++ b/driver/vidc/src/msm_vidc_driver.c @@ -233,7 +233,7 @@ void print_vidc_buffer(u32 tag, const char *tag_str, const char *str, struct msm return; dbuf = (struct dma_buf *)vbuf->dmabuf; - if (dbuf && dbuf->file) { + if (dbuf && vbuf->dbuf_get && dbuf->file) { f_inode = file_inode(dbuf->file); if (f_inode) { inode_num = f_inode->i_ino; @@ -5477,7 +5477,6 @@ static void msm_vidc_close_helper(struct kref *kref) * So acquire lock before calling vb2q_deinit. */ inst_lock(inst, __func__); - msm_vidc_vb2_queue_deinit(inst); msm_vidc_v4l2_fh_deinit(inst); inst_unlock(inst, __func__); destroy_workqueue(inst->workq);