From cf32797c87e17ff0eb636f385f45d8c8f4ac1db2 Mon Sep 17 00:00:00 2001 From: pengcheng chen Date: Mon, 11 Jun 2018 11:00:08 +0800 Subject: [PATCH] osd: risk coverity bugs in osd module PD#168947: osd: risk coverity bugs in osd module Change-Id: Ia593f55c1debbd5dca271461336edb29123fae00 Signed-off-by: pengcheng chen --- drivers/amlogic/media/osd/osd_drm.c | 11 +++- drivers/amlogic/media/osd/osd_fb.c | 42 ++++-------- drivers/amlogic/media/osd/osd_hw.c | 121 ++++++++++++++++++----------------- drivers/amlogic/media/osd/osd_rdma.c | 2 - 4 files changed, 83 insertions(+), 93 deletions(-) diff --git a/drivers/amlogic/media/osd/osd_drm.c b/drivers/amlogic/media/osd/osd_drm.c index fc6f7cd..6d6c6e9 100644 --- a/drivers/amlogic/media/osd/osd_drm.c +++ b/drivers/amlogic/media/osd/osd_drm.c @@ -61,6 +61,8 @@ static int parse_para(const char *para, int para_num, int *result) params = kstrdup(para, GFP_KERNEL); params_base = params; token = params; + if (!token) + return 0; len = strlen(token); do { token = strsep(¶ms, " "); @@ -74,6 +76,8 @@ static int parse_para(const char *para, int para_num, int *result) ret = kstrtoint(token, 0, &res); if (ret < 0) break; + if (!token) + return 0; len = strlen(token); *out++ = res; count++; @@ -217,7 +221,7 @@ static ssize_t free_scale_read_file(struct file *file, char __user *userbuf, unsigned int free_scale_enable; osd_get_free_scale_enable_hw(osd_id, &free_scale_enable); - len = snprintf(buf, PAGE_SIZE, "free_scale_enable:[0x%x]\n", + len = snprintf(buf, 128, "free_scale_enable:[0x%x]\n", free_scale_enable); return simple_read_from_buffer(userbuf, count, ppos, buf, len); } @@ -697,9 +701,10 @@ void osd_drm_debugfs_add( plane_osd_id[osd_id] = osd_id; *plane_debugfs_dir = debugfs_create_dir(name, osd_debugfs_root); - if (!plane_debugfs_dir) + if (!*plane_debugfs_dir) { osd_log_info("debugfs_create_dir failed: name=%s\n", name); - + return; + } for (i = 0; i < ARRAY_SIZE(osd_drm_debugfs_files); i++) { ent = debugfs_create_file(osd_drm_debugfs_files[i].name, osd_drm_debugfs_files[i].mode, diff --git a/drivers/amlogic/media/osd/osd_fb.c b/drivers/amlogic/media/osd/osd_fb.c index 35b7511..7422400 100644 --- a/drivers/amlogic/media/osd/osd_fb.c +++ b/drivers/amlogic/media/osd/osd_fb.c @@ -728,7 +728,7 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) u32 block_windows[8] = {0}; u32 block_mode; u32 hwc_enable; - int ret; + int ret = 0; s32 vsync_timestamp; s64 vsync_timestamp_64; u32 flush_rate; @@ -1021,6 +1021,8 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) case FBIOGET_OSD_DMABUF: #ifdef CONFIG_ION if (osd_get_afbc(info->node)) { + if (dmaexp.buffer_idx > OSD_MAX_BUF_NUM - 1) + dmaexp.buffer_idx = OSD_MAX_BUF_NUM - 1; dmaexp.fd = ion_share_dma_buf_fd( fb_ion_client, @@ -1444,7 +1446,8 @@ static int malloc_osd_memory(struct fb_info *info) static int osd_open(struct fb_info *info, int arg) { - u32 fb_index, logo_index; + u32 fb_index; + int logo_index; struct osd_fb_dev_s *fbdev; struct fb_fix_screeninfo *fix = NULL; int ret = 0; @@ -2014,6 +2017,8 @@ static int parse_para(const char *para, int para_num, int *result) params = kstrdup(para, GFP_KERNEL); params_base = params; token = params; + if (!token) + return 0; len = strlen(token); do { token = strsep(¶ms, " "); @@ -2027,6 +2032,8 @@ static int parse_para(const char *para, int para_num, int *result) ret = kstrtoint(token, 0, &res); if (ret < 0) break; + if (!token) + return 0; len = strlen(token); *out++ = res; count++; @@ -2447,29 +2454,6 @@ static ssize_t store_antiflicker(struct device *device, return count; } -static ssize_t show_update_freescale(struct device *device, - struct device_attribute *attr, - char *buf) -{ - unsigned int update_state = 0; - - return snprintf(buf, PAGE_SIZE, "update_state:[%s]\n", - update_state ? "TRUE" : "FALSE"); -} - -static ssize_t store_update_freescale(struct device *device, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned int update_state = 0; - int res = 0; - int ret = 0; - - ret = kstrtoint(buf, 0, &res); - update_state = res; - return count; -} - static ssize_t show_ver_clone(struct device *device, struct device_attribute *attr, char *buf) @@ -3073,8 +3057,6 @@ static struct device_attribute osd_attrs[] = { show_osd_reverse, store_osd_reverse), __ATTR(osd_antiflicker, 0644, show_antiflicker, store_antiflicker), - __ATTR(update_freescale, 0644, - show_update_freescale, store_update_freescale), __ATTR(ver_clone, 0644, show_ver_clone, store_ver_clone), __ATTR(ver_update_pan, 0220, @@ -3639,6 +3621,8 @@ static int osd_probe(struct platform_device *pdev) vinfo = get_current_vinfo(); for (index = 0; index < osd_meson_dev.osd_count; index++) { /* register frame buffer memory */ + if (index > OSD_COUNT - 1) + break; if (!fb_memsize[index + 1]) continue; fbi = framebuffer_alloc(sizeof(struct osd_fb_dev_s), @@ -3784,6 +3768,8 @@ static int osd_remove(struct platform_device *pdev) for (i = 0; i < osd_meson_dev.osd_count; i++) { int j; + if (i > OSD_COUNT - 1) + break; if (gp_fbdev_list[i]) { struct osd_fb_dev_s *fbdev = gp_fbdev_list[i]; @@ -3800,7 +3786,7 @@ static int osd_remove(struct platform_device *pdev) } iounmap(fbdev->fb_mem_vaddr); if (osd_get_afbc(i)) { - for (j = 1; j < OSD_MAX_BUF_NUM; j++) + for (j = 0; j < OSD_MAX_BUF_NUM; j++) iounmap(fbdev->fb_mem_afbc_vaddr[j]); } kfree(fbi->pseudo_palette); diff --git a/drivers/amlogic/media/osd/osd_hw.c b/drivers/amlogic/media/osd/osd_hw.c index e2be8f7..97666f9 100644 --- a/drivers/amlogic/media/osd/osd_hw.c +++ b/drivers/amlogic/media/osd/osd_hw.c @@ -911,14 +911,14 @@ static int sync_render_single_fence(u32 index, u32 yres, int out_fence_fd = -1; int buf_num = 0; u32 xoffset, yoffset; - struct osd_fence_map_s *fence_map = - kzalloc(sizeof(struct osd_fence_map_s), GFP_KERNEL); + struct osd_fence_map_s *fence_map = NULL; if (index > OSD1) return -1; xoffset = request->xoffset; yoffset = request->yoffset; buf_num = find_buf_num(yres, yoffset); + fence_map = kzalloc(sizeof(struct osd_fence_map_s), GFP_KERNEL); if (!fence_map) { osd_log_err("could not allocate osd_fence_map\n"); return -ENOMEM; @@ -1448,9 +1448,10 @@ void walk_through_update_list(void) for (i = 0; i < HW_OSD_COUNT; i++) { j = 0; - while (osd_hw.updated[i] && j < 32) { + while (osd_hw.updated[i] && j < HW_REG_INDEX_MAX) { if (osd_hw.updated[i] & (1 << j)) { - osd_hw.reg[j].update_func(i); + if (osd_hw.reg[j].update_func) + osd_hw.reg[j].update_func(i); remove_from_update_list(i, j); } j++; @@ -1488,9 +1489,22 @@ static u32 osd_get_hw_reset_flag(void) /* same bit, but gxm only reset hardware, not top reg*/ if (osd_hw.osd_afbcd[OSD1].enable) hw_reset_flag |= HW_RESET_AFBCD_HARDWARE; -#ifndef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM + if (((hdr_osd_reg.viu_osd1_matrix_ctrl & 0x00000001) + != 0x0) || + ((hdr_osd_reg.viu_osd1_eotf_ctl & 0x80000000) + != 0) || + ((hdr_osd_reg.viu_osd1_oetf_ctl & 0xe0000000) + != 0)) { + hw_reset_flag |= HW_RESET_OSD1_REGS; + osd_hdr_on = true; + } else if (osd_hdr_on) { + hw_reset_flag |= HW_RESET_OSD1_REGS; + osd_hdr_on = false; + } +#endif break; -#else +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM case __MESON_CPU_MAJOR_ID_GXL: case __MESON_CPU_MAJOR_ID_TXL: if (((hdr_osd_reg.viu_osd1_matrix_ctrl & 0x00000001) @@ -1699,8 +1713,10 @@ void osd_set_afbc(u32 index, u32 enable) u32 osd_get_afbc(u32 index) { u32 afbc_type = 0; + u32 afbc_enalbe; - if (osd_hw.osd_afbcd[index].enable) { + afbc_enalbe = osd_hw.osd_afbcd[index].enable; + if (afbc_enalbe) { if (osd_hw.osd_meson_dev.cpu_id == __MESON_CPU_MAJOR_ID_GXM) afbc_type = 1; @@ -2557,20 +2573,24 @@ void osd_get_flush_rate_hw(u32 *break_rate) void osd_set_antiflicker_hw(u32 index, struct vinfo_s *vinfo, u32 yres) { +#ifdef NEED_ANTIFLICKER bool osd_need_antiflicker = false; if (is_interlaced(vinfo)) osd_need_antiflicker = false; + else + osd_need_antiflicker = true; if (osd_need_antiflicker) { osd_hw.antiflicker_mode = 1; osd_antiflicker_task_start(); osd_antiflicker_enable(1); osd_antiflicker_update_pan(osd_hw.pandata[index].y_start, yres); - } else { - if (osd_hw.antiflicker_mode) - osd_antiflicker_task_stop(); - osd_hw.antiflicker_mode = 0; } +#else + if (osd_hw.antiflicker_mode) + osd_antiflicker_task_stop(); + osd_hw.antiflicker_mode = 0; +#endif } void osd_get_antiflicker_hw(u32 index, u32 *on_off) @@ -4872,16 +4892,15 @@ static int check_order_continuous(u32 *order) } -static int blend_din_to_osd( +static u32 blend_din_to_osd( u32 blend_din_index, struct hw_osd_blending_s *blending) { u32 osd_index = 0; osd_index = blending->osd_to_bdin_table[blend_din_index]; - if ((osd_index > OSD3) - || (osd_index < OSD1)) - return -1; + if (osd_index > OSD3) + return OSD_MAX; else return osd_index; } @@ -4940,7 +4959,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) break; case 2: { - int temp_index[2]; + int temp_index[2] = {0}; int j = 0; for (i = 0; i < osd_count; i++) { @@ -5061,51 +5080,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending) blending->osd_to_bdin_table[3]); blending->blend_reg.din_reoder_sel = blending->din_reoder_sel; - osd_log_dbg("blend_din1 == osd%d\n", - blend_din_to_osd(BLEND_DIN1, blending) + 1); - osd_log_dbg("blend_din3 == osd%d\n", - blend_din_to_osd(BLEND_DIN3, blending) + 1); - osd_log_dbg("blend_din4 == osd%d\n", - blend_din_to_osd(BLEND_DIN4, blending) + 1); -} - -#if 0 -static void adjust_blend_din_table(struct hw_osd_blending_s *blending) -{ - int i = 0; - - /* adjust osd_to_bdin_table */ - /* reorder[i] = osd[i]'s display layer */ - /* tow osd_x input to vpp, default osd2 is top */ - blending->din_reoder_sel = 0; - for (i = 0; i < osd_hw.osd_meson_dev.osd_count - 1; i++) { - switch (blending->reorder[i]) { - /* blend_din1 is top, blend_din(3 4) is bottom layer */ - case LAYER_1: - blending->din_reoder_sel |= (i + 1) << 8;//blend_din3 - blending->osd_to_bdin_table[2] = i;//blend_din3 -- osdx - break; - case LAYER_2: - blending->din_reoder_sel |= (i + 1) << 0;//blend_din1 - blending->osd_to_bdin_table[0] = i;//blend_din4 -- osdx - break; - case LAYER_3: - blending->din_reoder_sel |= (i + 1) << 12;//blend_din4 - blending->osd_to_bdin_table[3] = i;//blend_din4 -- osdx - break; - } - } - osd_log_dbg("osd_to_bdin_table[i]=[%x,%x,%x,%x]\n", - blending->osd_to_bdin_table[0], - blending->osd_to_bdin_table[1], - blending->osd_to_bdin_table[2], - blending->osd_to_bdin_table[3]); - osd_log_dbg("blending->din_reoder_sel=%d\n", - blending->din_reoder_sel); - blending->blend_reg.din_reoder_sel = - blending->din_reoder_sel; } -#endif static bool is_freescale_para_changed(u32 index) { @@ -5349,6 +5324,8 @@ static void osd_setting_blend0(struct hw_osd_blending_s *blending) if (layer_blend->input1 != BLEND_NO_DIN) { /* calculate osd blend din scope */ index = blend_din_to_osd(layer_blend->input1, blending); + if (index >= OSD_MAX) + return; bld_osd_h_start = layer_blend->input1_data.x; bld_osd_h_end = @@ -5426,6 +5403,8 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending) if (layer_blend->input1 != BLEND_NO_DIN) { index = blend_din_to_osd(layer_blend->input1, blending); + if (index >= OSD_MAX) + return; /* calculate osd blend din scope */ bld_osd_h_start = layer_blend->input1_data.x; @@ -5450,6 +5429,8 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending) } if (layer_blend->input2 != BLEND_NO_DIN) { index = blend_din_to_osd(layer_blend->input2, blending); + if (index >= OSD_MAX) + return; /* calculate osd blend din scope */ bld_osd_h_start = layer_blend->input2_data.x; @@ -5844,6 +5825,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) layer_blend->input1 |= BYPASS_DIN; layer_blend->input2 = BLEND_NO_DIN; index = blend_din_to_osd(BLEND_DIN1, blending); + if (index >= OSD_MAX) + return; osd_setting_blend0_input(index, blending); osd_setting_blend0(blending); @@ -5903,6 +5886,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) layer_blend->input1 = input1; layer_blend->input2 = BLEND_NO_DIN; index = blend_din_to_osd(input1, blending); + if (index >= OSD_MAX) + return; osd_setting_blend0_input(index, blending); if (index != OSD1) { /* here used freescale osd1/osd2 */ @@ -5916,6 +5901,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) sizeof(struct dispdata_s)); index = blend_din_to_osd(input2, blending); + if (index >= OSD_MAX) + return; if (index != OSD1) { osd_log_dbg("before blend1: set osd%d freescale\n", index); @@ -5978,6 +5965,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) layer_blend->input1 |= BYPASS_DIN; layer_blend->input2 = BLEND_NO_DIN; index = blend_din_to_osd(BLEND_DIN1, blending); + if (index >= OSD_MAX) + return; osd_setting_blend0_input(index, blending); osd_setting_blend0(blending); @@ -6007,6 +5996,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_hw.free_dst_data[index].y_start + 1; index = blend_din_to_osd(BLEND_DIN4, blending); + if (index >= OSD_MAX) + return; /* here freescale osd1/osd2 used */ osd_log_dbg("before blend1: set osd%d freescale\n", index); osd_set_freescale(index, blending->background_w, @@ -6063,6 +6054,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) layer_blend->input1 = input1; layer_blend->input2 = BLEND_NO_DIN; index = blend_din_to_osd(input1, blending); + if (index >= OSD_MAX) + return; osd_setting_blend0_input(index, blending); if (index != OSD1) osd_log_err("not support case!!!\n"); @@ -6090,6 +6083,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_hw.free_dst_data[index].y_end - osd_hw.free_dst_data[index].y_start + 1; index = blend_din_to_osd(layer_blend->input2, blending); + if (index >= OSD_MAX) + return; if (index != OSD1) { osd_log_dbg("before blend1: set osd%d freescale\n", index); @@ -6139,6 +6134,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) layer_blend->input1 |= BYPASS_DIN; layer_blend->input2 = BLEND_NO_DIN; index = blend_din_to_osd(BLEND_DIN1, blending); + if (index >= OSD_MAX) + return; osd_setting_blend0_input(index, blending); osd_setting_blend0(blending); @@ -6168,6 +6165,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_hw.free_dst_data[index].y_start + 1; index = blend_din_to_osd(BLEND_DIN3, blending); + if (index >= OSD_MAX) + return; osd_log_dbg("before blend1: set osd%d freescale\n", index); osd_set_freescale(index, blending->background_w, blending->background_h, blending); @@ -6183,6 +6182,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending) osd_hw.free_dst_data[index].y_start + 1; index = blend_din_to_osd(BLEND_DIN4, blending); + if (index >= OSD_MAX) + return; osd_log_dbg("before blend1: set osd%d freescale\n", index); osd_set_freescale(index, blending->background_w, blending->background_h, blending); diff --git a/drivers/amlogic/media/osd/osd_rdma.c b/drivers/amlogic/media/osd/osd_rdma.c index 03cab43..e383a2d 100644 --- a/drivers/amlogic/media/osd/osd_rdma.c +++ b/drivers/amlogic/media/osd/osd_rdma.c @@ -62,7 +62,6 @@ int rdma_reset_tigger_flag; static DEFINE_SPINLOCK(rdma_lock); static struct rdma_table_item *rdma_table; static struct device *osd_rdma_dev; -static struct page *table_pages; static void *osd_rdma_table_virt; static dma_addr_t osd_rdma_table_phy; static u32 table_paddr; @@ -1338,7 +1337,6 @@ static int osd_rdma_init(void) goto error1; } of_dma_configure(osd_rdma_dev, osd_rdma_dev->of_node); - table_pages = dma_alloc_from_contiguous(osd_rdma_dev, 1, 4); osd_rdma_table_virt = dma_alloc_coherent(osd_rdma_dev, PAGE_SIZE, &osd_rdma_table_phy, GFP_KERNEL); -- 2.7.4