From 2768f69bba74bdeda3fc412f6126e715aa51faee Mon Sep 17 00:00:00 2001 From: Guchun Chen Date: Fri, 9 Mar 2018 16:14:14 +0800 Subject: [PATCH] drm: msm: sde: fix potential NULL pointer dereference Pointer should be checked after returning from function or being passed from other function. So add checker for this to avoid NULL pointer dereference. Change-Id: Ie86f47230b50433e08259ee5f6bbb52bedf749b1 CRs-Fixed: 2202957 Signed-off-by: Guchun Chen --- drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c | 4 ++-- drivers/gpu/drm/msm/sde/sde_crtc.c | 15 ++++++++++++++- drivers/gpu/drm/msm/sde/sde_kms.c | 6 ++++-- drivers/gpu/drm/msm/sde/sde_plane.c | 21 ++++++++++++++++----- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c index 35ba396e1cd1..a79702306159 100644 --- a/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c +++ b/drivers/gpu/drm/msm/hdmi-staging/sde_hdmi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -1600,7 +1600,7 @@ static int _sde_hdmi_ext_disp_init(struct sde_hdmi *display) const char *phandle = "qcom,msm_ext_disp"; if (!display) { - SDE_ERROR("[%s]Invalid params\n", display->name); + SDE_ERROR("Invalid params\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index 2a31bc7fedc7..1a0ce00a7d44 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -240,6 +240,10 @@ static void _sde_crtc_blend_setup_mixer(struct drm_crtc *crtc, plane->state->fb->base.id : -1); format = to_sde_format(msm_framebuffer_format(pstate->base.fb)); + if (!format) { + SDE_ERROR("%s: get sde format failed\n", __func__); + return; + } /* blend config update */ if (pstate->stage != SDE_STAGE_BASE) { @@ -915,6 +919,11 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc) dev = crtc->dev; sde_crtc = to_sde_crtc(crtc); sde_kms = _sde_crtc_get_kms(crtc); + if (!sde_kms) { + SDE_ERROR("invalid sde_kms\n"); + return; + } + priv = sde_kms->dev->dev_private; /* @@ -1541,6 +1550,10 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, sde_crtc = to_sde_crtc(crtc); dev = crtc->dev; sde_kms = _sde_crtc_get_kms(crtc); + if (!sde_kms) { + SDE_ERROR("invalid sde_kms\n"); + return; + } info = kzalloc(sizeof(struct sde_kms_info), GFP_KERNEL); if (!info) { diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index 34a32d79f22c..93b8a69597a5 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -385,7 +385,7 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms, struct drm_crtc *crtc) { struct drm_encoder *encoder; - struct drm_device *dev = crtc->dev; + struct drm_device *dev; int ret; if (!kms || !crtc || !crtc->state) { @@ -393,6 +393,8 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms, return; } + dev = crtc->dev; + if (!crtc->state->enable) { SDE_DEBUG("[crtc:%d] not enable\n", crtc->base.id); return; diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c index f5f125c3f71c..43ff508975dd 100644 --- a/drivers/gpu/drm/msm/sde/sde_plane.c +++ b/drivers/gpu/drm/msm/sde/sde_plane.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (C) 2014-2018 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -303,6 +303,11 @@ static void _sde_plane_set_qos_lut(struct sde_phy_plane *pp, fb->pixel_format, fb->modifier, drm_format_num_planes(fb->pixel_format)); + if (!fmt) { + SDE_ERROR("%s: faile to get fmt\n", __func__); + return; + } + total_fl = _sde_plane_calc_fill_level(pp, fmt, pp->pipe_cfg.src_rect.w); @@ -362,6 +367,10 @@ static void _sde_plane_set_danger_lut(struct sde_phy_plane *pp, fb->pixel_format, fb->modifier, drm_format_num_planes(fb->pixel_format)); + if (!fmt) { + SDE_ERROR("%s: fail to get fmt\n", __func__); + return; + } if (SDE_FORMAT_IS_LINEAR(fmt)) { danger_lut = pp->pipe_sblk->danger_lut_linear; @@ -694,11 +703,11 @@ static inline void _sde_plane_set_scanout(struct sde_phy_plane *pp, static int _sde_plane_setup_scaler3_lut(struct sde_phy_plane *pp, struct sde_plane_state *pstate) { - struct sde_plane *psde = pp->sde_plane; + struct sde_plane *psde; struct sde_hw_scaler3_cfg *cfg; int ret = 0; - if (!pp || !pp->scaler3_cfg) { + if (!pp || !pp->sde_plane || !pp->scaler3_cfg) { SDE_ERROR("invalid args\n"); return -EINVAL; } else if (!pstate) { @@ -707,6 +716,7 @@ static int _sde_plane_setup_scaler3_lut(struct sde_phy_plane *pp, return -EINVAL; } + psde = pp->sde_plane; cfg = pp->scaler3_cfg; cfg->dir_lut = msm_property_get_blob( @@ -1450,7 +1460,7 @@ static int _sde_plane_mode_set(struct drm_plane *plane, static int sde_plane_prepare_fb(struct drm_plane *plane, const struct drm_plane_state *new_state) { - struct drm_framebuffer *fb = new_state->fb; + struct drm_framebuffer *fb; struct sde_plane *psde = to_sde_plane(plane); struct sde_plane_state *pstate; int rc; @@ -1461,6 +1471,7 @@ static int sde_plane_prepare_fb(struct drm_plane *plane, if (!new_state->fb) return 0; + fb = new_state->fb; pstate = to_sde_plane_state(new_state); rc = _sde_plane_get_aspace(psde, pstate, &psde->aspace); @@ -1800,7 +1811,7 @@ static void _sde_plane_install_properties(struct drm_plane *plane, {SDE_DRM_FB_NON_SEC_DIR_TRANS, "non_sec_direct_translation"}, {SDE_DRM_FB_SEC_DIR_TRANS, "sec_direct_translation"}, }; - const struct sde_format_extended *format_list; + const struct sde_format_extended *format_list = NULL; struct sde_kms_info *info; struct sde_plane *psde = to_sde_plane(plane); int zpos_max = 255;