From 0cbfaf1a4b25cd3a80566317a4e1fc75fed96d54 Mon Sep 17 00:00:00 2001 From: Samantha Tran Date: Fri, 17 May 2019 11:30:48 -0700 Subject: [PATCH] disp: msm: fix out-of-bound access and NULL dereference Fix possible out-of-bound access and NULL pointer dereference in SDE and PLL driver. Change-Id: Ic5c34b3b4c3e983413a0351c38206cf3f3ab3b1f Signed-off-by: Samantha Tran --- msm/sde/sde_encoder.c | 3 ++- msm/sde/sde_hw_catalog.c | 11 ++++------- msm/sde/sde_hw_reg_dma_v1_color_proc.c | 2 ++ msm/sde/sde_plane.c | 27 ++++++++++++++++++++------ pll/pll_drv.c | 5 ++++- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index be393d993178..4d43c4f411a4 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -1387,7 +1387,8 @@ static int _sde_encoder_dsc_2_lm_2_enc_2_intf(struct sde_encoder_virt *sde_enc, SDE_DEBUG_ENC(sde_enc, "pic_w: %d pic_h: %d mode:%d\n", roi->w, roi->h, dsc_common_mode); - for (i = 0; i < sde_enc->num_phys_encs; i++) { + for (i = 0; i < sde_enc->num_phys_encs && + i < MAX_CHANNELS_PER_ENC; i++) { bool active = !!((1 << i) & params->affected_displays); SDE_EVT32(DRMID(&sde_enc->base), roi->w, roi->h, diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 9052e0fe262e..b4ae00f5384b 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -2588,19 +2588,16 @@ static int sde_uidle_parse_dt(struct device_node *np, if (!sde_cfg) { SDE_ERROR("invalid argument\n"); - rc = -EINVAL; - goto end; + return -EINVAL; } if (!sde_cfg->uidle_cfg.uidle_rev) - goto end; + return 0; prop_value = kcalloc(UIDLE_PROP_MAX, sizeof(struct sde_prop_value), GFP_KERNEL); - if (!prop_value) { - rc = -ENOMEM; - goto end; - } + if (!prop_value) + return -ENOMEM; rc = _validate_dt_entry(np, uidle_prop, ARRAY_SIZE(uidle_prop), prop_count, &off_count); diff --git a/msm/sde/sde_hw_reg_dma_v1_color_proc.c b/msm/sde/sde_hw_reg_dma_v1_color_proc.c index 3f38a17d2fa9..71ddd28ccd54 100644 --- a/msm/sde/sde_hw_reg_dma_v1_color_proc.c +++ b/msm/sde/sde_hw_reg_dma_v1_color_proc.c @@ -2267,6 +2267,7 @@ void reg_dmav1_setup_vig_igcv5(struct sde_hw_pipe *ctx, void *cfg) if (!igc_lut) { DRM_DEBUG_DRIVER("disable igc feature\n"); vig_igcv5_off(ctx, hw_cfg); + return; } dma_ops = sde_reg_dma_get_ops(); @@ -2317,6 +2318,7 @@ void reg_dmav1_setup_vig_igcv6(struct sde_hw_pipe *ctx, void *cfg) DRM_DEBUG_DRIVER("disable igc feature\n"); /* Both v5 and v6 call same igcv5_off */ vig_igcv5_off(ctx, hw_cfg); + return; } dma_ops = sde_reg_dma_get_ops(); diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 5eced69d2b56..35d0748b9601 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -2818,10 +2818,7 @@ static void _sde_plane_setup_uidle(struct drm_crtc *crtc, SDE_ERROR("invalid settings, will disable UIDLE %d %d %d %d\n", line_time, fal10_threshold, fal10_target_idle_time_ns, fal1_target_idle_time_ns); - cfg.enable = false; - cfg.fal10_threshold = 0; - cfg.fal1_threshold = 0; - cfg.fal_allowed_threshold = 0; + memset(&cfg, 0, sizeof(struct sde_hw_pipe_uidle_cfg)); } SDE_DEBUG_PLANE(psde, @@ -2863,6 +2860,7 @@ static void _sde_plane_update_roi_config(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb) { const struct sde_format *fmt; + const struct msm_format *msm_fmt; struct sde_plane *psde; struct drm_plane_state *state; struct sde_plane_state *pstate; @@ -2875,7 +2873,15 @@ static void _sde_plane_update_roi_config(struct drm_plane *plane, state = plane->state; pstate = to_sde_plane_state(state); - fmt = to_sde_format(msm_framebuffer_format(fb)); + + msm_fmt = msm_framebuffer_format(fb); + if (!msm_fmt) { + SDE_ERROR("crtc%d plane%d: null format\n", + DRMID(crtc), DRMID(plane)); + return; + } + + fmt = to_sde_format(msm_fmt); POPULATE_RECT(&src, state->src_x, state->src_y, state->src_w, state->src_h, q16_data); @@ -3033,6 +3039,7 @@ static void _sde_plane_update_properties(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb) { uint32_t nplanes; + const struct msm_format *msm_fmt; const struct sde_format *fmt; struct sde_plane *psde; struct drm_plane_state *state; @@ -3042,7 +3049,15 @@ static void _sde_plane_update_properties(struct drm_plane *plane, state = plane->state; pstate = to_sde_plane_state(state); - fmt = to_sde_format(msm_framebuffer_format(fb)); + + msm_fmt = msm_framebuffer_format(fb); + if (!msm_fmt) { + SDE_ERROR("crtc%d plane%d: null format\n", + DRMID(crtc), DRMID(plane)); + return; + } + + fmt = to_sde_format(msm_fmt); nplanes = fmt->num_planes; /* update secure session flag */ diff --git a/pll/pll_drv.c b/pll/pll_drv.c index 80ae1b0f7471..4b5c9fb178ee 100644 --- a/pll/pll_drv.c +++ b/pll/pll_drv.c @@ -208,9 +208,12 @@ static inline int mdss_pll_get_ioresurces(struct platform_device *pdev, struct resource *rsc = platform_get_resource_byname(pdev, IORESOURCE_MEM, resource_name); if (rsc) { + if (!regmap) + return -ENOMEM; + *regmap = devm_ioremap(&pdev->dev, rsc->start, resource_size(rsc)); - if (!regmap) + if (!*regmap) return -ENOMEM; } return rc;