From 03aa4bdcdf1825497cfbaf6dae4cdf28284e5e37 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Wed, 20 Jan 2021 14:25:45 +0900 Subject: [PATCH] amlogic/media: lcd: Fix division by zero If no lcd is set by bootargs, it can not choose lcd type from device tree and it causes division by zero. Fix the it by checking division value. This fixes below ubsan warnings: UBSAN: Undefined behaviour in drivers/amlogic/media/vout/lcd/lcd_common.c:777:59 UBSAN: Undefined behaviour in drivers/amlogic/media/vout/lcd/lcd_common.c:778:43 UBSAN: Undefined behaviour in drivers/amlogic/media/vout/lcd/lcd_common.c:784:53 UBSAN: Undefined behaviour in drivers/amlogic/media/vout/lcd/lcd_common.c:786:59 UBSAN: Undefined behaviour in drivers/amlogic/media/vout/lcd/lcd_common.c:787:43 division by zero ... [ffffff9200003610+ 96][] __ubsan_handle_divrem_overflow+0x8c/0xc8 [ffffff9200003670+ 144][] lcd_timing_init_config+0x254/0x390 [ffffff9200003700+ 544][] lcd_tablet_probe+0xfa0/0x3f50 [ffffff9200003920+ 64][] lcd_mode_probe+0x54/0x6c0 [ffffff9200003960+ 272][] lcd_probe+0x984/0x1070 ... Change-Id: I6ad73fcd554715c1d7ac3cadf82ead251b596e1c Signed-off-by: Seung-Woo Kim --- drivers/amlogic/media/vout/lcd/lcd_common.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/amlogic/media/vout/lcd/lcd_common.c b/drivers/amlogic/media/vout/lcd/lcd_common.c index 0f7f90bdd673..237a46522e81 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_common.c +++ b/drivers/amlogic/media/vout/lcd/lcd_common.c @@ -774,17 +774,28 @@ void lcd_timing_init_config(struct lcd_config_s *pconf) pconf->lcd_timing.de_vs_addr = de_vstart; pconf->lcd_timing.de_ve_addr = de_vstart + v_active - 1; - hstart = (de_hstart + h_period - hsync_bp - hsync_width) % h_period; - hend = (de_hstart + h_period - hsync_bp) % h_period; + if (h_period) { + hstart = (de_hstart + h_period - hsync_bp - hsync_width) % h_period; + hend = (de_hstart + h_period - hsync_bp) % h_period; + } else { + hstart = 0; + hend = 0; + } pconf->lcd_timing.hs_hs_addr = hstart; pconf->lcd_timing.hs_he_addr = hend; pconf->lcd_timing.hs_vs_addr = 0; pconf->lcd_timing.hs_ve_addr = v_period - 1; - pconf->lcd_timing.vs_hs_addr = (hstart + h_period) % h_period; + if (h_period) { + pconf->lcd_timing.vs_hs_addr = (hstart + h_period) % h_period; + vstart = (de_vstart + v_period - vsync_bp - vsync_width) % v_period; + vend = (de_vstart + v_period - vsync_bp) % v_period; + } else { + pconf->lcd_timing.vs_hs_addr = 0; + vstart = 0; + vend = 0; + } pconf->lcd_timing.vs_he_addr = pconf->lcd_timing.vs_hs_addr; - vstart = (de_vstart + v_period - vsync_bp - vsync_width) % v_period; - vend = (de_vstart + v_period - vsync_bp) % v_period; pconf->lcd_timing.vs_vs_addr = vstart; pconf->lcd_timing.vs_ve_addr = vend; -- 2.34.1