From e50341f06275ec466d3607d4d5bbfa83f8098cdd Mon Sep 17 00:00:00 2001 From: Peng Yixin Date: Fri, 7 Dec 2018 10:26:19 +0800 Subject: [PATCH] media: fix some KASAN bug: [1/1] PD#OTT-945 Problem: KASAN detected some "use-after-free" bug. Solution: Fixed these bug. Verify: Verified p212 Change-Id: If7e87987d26338e25dcca909ed52676794ccdaed Signed-off-by: Peng Yixin --- .../frame_provider/decoder/h264_multi/vmh264.c | 13 +++++++++++++ .../frame_provider/decoder/h265/vh265.c | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c index f7b23d005cfd..b6870456a343 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h264_multi/vmh264.c @@ -812,6 +812,7 @@ struct vdec_h264_hw_s { void *v4l2_ctx; wait_queue_head_t wait_q; u32 reg_g_status; + struct mutex chunks_mutex; }; static u32 again_threshold = 0x40; @@ -4783,6 +4784,7 @@ pic_done_proc: = 1; } #endif + mutex_lock(&hw->chunks_mutex); if (hw->chunk) { p_H264_Dpb->mVideo.dec_picture->pts = hw->chunk->pts; @@ -4827,6 +4829,7 @@ pic_done_proc: #endif } } + mutex_unlock(&hw->chunks_mutex); check_decoded_pic_error(hw); #ifdef ERROR_HANDLE_TEST if ((hw->data_flag & ERROR_FLAG) @@ -5783,6 +5786,7 @@ static s32 vh264_init(struct vdec_h264_hw_s *hw) hw->stat |= STAT_TIMER_ARM; hw->stat |= STAT_ISR_REG; + mutex_init(&hw->chunks_mutex); vh264_local_init(hw); INIT_WORK(&hw->work, vh264_work); INIT_WORK(&hw->notify_work, vh264_notify_work); @@ -6774,7 +6778,10 @@ static void vh264_work(struct work_struct *work) READ_VREG(VLD_MEM_VIFIFO_LEVEL), READ_VREG(VLD_MEM_VIFIFO_WP), READ_VREG(VLD_MEM_VIFIFO_RP)); + mutex_lock(&hw->chunks_mutex); vdec_vframe_dirty(vdec, hw->chunk); + hw->chunk = NULL; + mutex_unlock(&hw->chunks_mutex); vdec_clean_input(vdec); } if ((hw->dec_result == DEC_RESULT_GET_DATA_RETRY) && @@ -6893,7 +6900,10 @@ result_done: READ_VREG(VLD_MEM_VIFIFO_LEVEL), READ_VREG(VLD_MEM_VIFIFO_WP), READ_VREG(VLD_MEM_VIFIFO_RP)); + mutex_lock(&hw->chunks_mutex); vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); + hw->chunk = NULL; + mutex_unlock(&hw->chunks_mutex); } else if (hw->dec_result == DEC_RESULT_AGAIN) { /* stream base: stream buf empty or timeout @@ -6917,7 +6927,10 @@ result_done: flush_dpb(p_H264_Dpb); if (hw->is_used_v4l) notify_v4l_eos(hw_to_vdec(hw)); + mutex_lock(&hw->chunks_mutex); vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); + hw->chunk = NULL; + mutex_unlock(&hw->chunks_mutex); vdec_clean_input(vdec); } else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) { dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS, diff --git a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c index 7865f4607e7c..041c673baeca 100644 --- a/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c +++ b/drivers/amlogic/media_modules/frame_provider/decoder/h265/vh265.c @@ -1642,6 +1642,7 @@ struct hevc_state_s { #endif u32 first_pic_flag; u32 decode_size; + struct mutex chunks_mutex; } /*hevc_stru_t */; #ifdef AGAIN_HAS_THRESHOLD @@ -7940,6 +7941,7 @@ static irqreturn_t vh265_isr_thread_fn(int irq, void *data) hevc->shift_byte_count_lo = i; } #ifdef MULTI_INSTANCE_SUPPORT + mutex_lock(&hevc->chunks_mutex); if ((dec_status == HEVC_DECPIC_DATA_DONE || dec_status == HEVC_FIND_NEXT_PIC_NAL || dec_status == HEVC_FIND_NEXT_DVEL_NAL) @@ -7947,6 +7949,7 @@ static irqreturn_t vh265_isr_thread_fn(int irq, void *data) hevc->cur_pic->pts = hevc->chunk->pts; hevc->cur_pic->pts64 = hevc->chunk->pts64; } + mutex_unlock(&hevc->chunks_mutex); if (dec_status == HEVC_DECODE_BUFEMPTY || dec_status == HEVC_DECODE_BUFEMPTY2) { @@ -9388,6 +9391,7 @@ static s32 vh265_init(struct hevc_state_s *hevc) if (vh265_local_init(hevc) < 0) return -EBUSY; + mutex_init(&hevc->chunks_mutex); INIT_WORK(&hevc->notify_work, vh265_notify_work); INIT_WORK(&hevc->set_clk_work, vh265_set_clk); @@ -9905,7 +9909,10 @@ static void vh265_work(struct work_struct *work) READ_VREG(HEVC_STREAM_WR_PTR), READ_VREG(HEVC_STREAM_RD_PTR), READ_VREG(HEVC_MPC_E)); + mutex_lock(&hevc->chunks_mutex); vdec_vframe_dirty(vdec, hevc->chunk); + hevc->chunk = NULL; + mutex_unlock(&hevc->chunks_mutex); vdec_clean_input(vdec); } @@ -10099,7 +10106,10 @@ static void vh265_work(struct work_struct *work) hevc->shift_byte_count_lo; } #endif + mutex_lock(&hevc->chunks_mutex); vdec_vframe_dirty(hw_to_vdec(hevc), hevc->chunk); + hevc->chunk = NULL; + mutex_unlock(&hevc->chunks_mutex); } else if (hevc->dec_result == DEC_RESULT_AGAIN) { /* stream base: stream buf empty or timeout @@ -10149,7 +10159,10 @@ static void vh265_work(struct work_struct *work) hevc->shift_byte_count_lo; } #endif + mutex_lock(&hevc->chunks_mutex); vdec_vframe_dirty(hw_to_vdec(hevc), hevc->chunk); + hevc->chunk = NULL; + mutex_unlock(&hevc->chunks_mutex); } else if (hevc->dec_result == DEC_RESULT_FORCE_EXIT) { hevc_print(hevc, PRINT_FLAG_VDEC_STATUS, "%s: force exit\n",