Browse Source

drm/msm/sde: Check for cur_master NULL dereference

Check if cur_master encoder exists before using the variable in
sde encoder. This will avoid possible NULL dereferences.

Change-Id: I003386cba392a0027f7e9e8441fd4671b57b9a03
Signed-off-by: Nilaan Gunabalachandran <[email protected]>
Nilaan Gunabalachandran 6 years ago
parent
commit
9b09b9af71
1 changed files with 26 additions and 5 deletions
  1. 26 5
      msm/sde/sde_encoder.c

+ 26 - 5
msm/sde/sde_encoder.c

@@ -1286,7 +1286,6 @@ static int _sde_encoder_dsc_n_lm_1_enc_1_intf(struct sde_encoder_virt *sde_enc)
 		return -EINVAL;
 	}
 
-
 	hw_ctl = enc_master->hw_ctl;
 
 	memset(&cfg, 0, sizeof(cfg));
@@ -1344,10 +1343,15 @@ static int _sde_encoder_dsc_2_lm_2_enc_2_intf(struct sde_encoder_virt *sde_enc,
 	struct sde_hw_pingpong *hw_dsc_pp[MAX_CHANNELS_PER_ENC];
 	struct msm_display_dsc_info dsc[MAX_CHANNELS_PER_ENC];
 	bool half_panel_partial_update;
-	struct sde_hw_ctl *hw_ctl = enc_master->hw_ctl;
+	struct sde_hw_ctl *hw_ctl = NULL;
 	struct sde_ctl_dsc_cfg cfg;
 	int i;
 
+	if (!enc_master) {
+		SDE_ERROR_ENC(sde_enc, "invalid encoder master for DSC\n");
+		return -EINVAL;
+	}
+
 	memset(&cfg, 0, sizeof(cfg));
 
 	for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
@@ -1361,6 +1365,8 @@ static int _sde_encoder_dsc_2_lm_2_enc_2_intf(struct sde_encoder_virt *sde_enc,
 		}
 	}
 
+	hw_ctl = enc_master->hw_ctl;
+
 	half_panel_partial_update =
 			hweight_long(params->affected_displays) == 1;
 
@@ -1460,10 +1466,15 @@ static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc,
 	struct sde_hw_pingpong *hw_dsc_pp[MAX_CHANNELS_PER_ENC];
 	struct msm_display_dsc_info *dsc = NULL;
 	bool half_panel_partial_update;
-	struct sde_hw_ctl *hw_ctl = enc_master->hw_ctl;
+	struct sde_hw_ctl *hw_ctl = NULL;
 	struct sde_ctl_dsc_cfg cfg;
 	int i;
 
+	if (!enc_master) {
+		SDE_ERROR_ENC(sde_enc, "invalid encoder master for DSC\n");
+		return -EINVAL;
+	}
+
 	memset(&cfg, 0, sizeof(cfg));
 
 	for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
@@ -1477,6 +1488,8 @@ static int _sde_encoder_dsc_2_lm_2_enc_1_intf(struct sde_encoder_virt *sde_enc,
 		}
 	}
 
+	hw_ctl = enc_master->hw_ctl;
+
 	dsc = &sde_enc->mode_info.comp_info.dsc_info;
 
 	half_panel_partial_update =
@@ -3029,9 +3042,12 @@ void sde_encoder_virt_restore(struct drm_encoder *drm_enc)
 		SDE_ERROR("invalid encoder\n");
 		return;
 	}
+
 	sde_enc = to_sde_encoder_virt(drm_enc);
-	memset(&sde_enc->cur_master->intf_cfg_v1, 0,
-			sizeof(sde_enc->cur_master->intf_cfg_v1));
+
+	if (sde_enc->cur_master)
+		memset(&sde_enc->cur_master->intf_cfg_v1, 0,
+				sizeof(sde_enc->cur_master->intf_cfg_v1));
 	sde_enc->idle_pc_restore = true;
 
 	for (i = 0; i < sde_enc->num_phys_encs; i++) {
@@ -4225,6 +4241,11 @@ static int _sde_encoder_wakeup_time(struct drm_encoder *drm_enc,
 	ktime_t cur_time;
 
 	sde_enc = to_sde_encoder_virt(drm_enc);
+	if (!sde_enc || !sde_enc->cur_master) {
+		SDE_ERROR("invalid sde encoder/master\n");
+		return -EINVAL;
+	}
+
 	mode = &sde_enc->cur_master->cached_mode;
 
 	line_time = _sde_encoder_calculate_linetime(sde_enc, mode);