video: driver: fix race issues with msm_vidc_stats_handler api

There are 2 possible race issues with msm_vidc_stats_handler.

[1] msm_vidc_close acquired inst->lock and called cancel_delayed_work,
by that time stats_handler already fired and incremented inst->kref
via get_inst_ref. Close sequence releases the lock and called
put_inst().
So now inst strong ref is held by stats_handler, which will acquire
inst->lock and schedules new stats_work and does put_inst. inst->kref
count reaches zero and it will free inst struct(using close_helper).
So that will lead to use-after-free crash at core kernel side.

[2] msm_vidc_close acquired inst->lock and called cancel_delayed_work,
by that time stats_handler is scheduled. So process_one_work() from
workqueue is ready to call stats_handler api. But before it invokes
stats handler(context switch), msm_vidc_close sequence continued to
run and completed the close sequence and called put_inst. So inst
struct got freed up(because inst->kref count reached to zero). Now if
core kernel(workqueue) attempts to invoke stats_handler by calling
worker->current_func(work), will lead to again use-after-free crash.

Added changes to avoid above mentioned issues.

Change-Id: I55bc33a753f4dbae4a8cdc6373b5465d183da3bc
Signed-off-by: Govindaraj Rajagopal <grajagop@codeaurora.org>
This commit is contained in:
Govindaraj Rajagopal
2021-10-12 16:54:37 +05:30
parent b1c38f2133
commit 2eb5672463
3 changed files with 19 additions and 9 deletions

View File

@@ -353,7 +353,8 @@ void msm_vidc_update_stats(struct msm_vidc_inst *inst,
struct msm_vidc_buffer *buf, enum msm_vidc_debugfs_event etype);
void msm_vidc_stats_handler(struct work_struct *work);
int schedule_stats_work(struct msm_vidc_inst *inst);
int cancel_stats_work(struct msm_vidc_inst *inst);
int cancel_stats_work_sync(struct msm_vidc_inst *inst);
void msm_vidc_print_stats(struct msm_vidc_inst *inst);
enum msm_vidc_buffer_type v4l2_type_to_driver(u32 type,
const char *func);
int msm_vidc_queue_buffer_single(struct msm_vidc_inst *inst,