DSC capabilities are given in bytes 11-13 of VSDB (i.e. bytes 8-10 of
SCDS). Since minimum length of Data block is 7, all bytes greater than 7
must be read only after checking the length of the data block.

This patch adds check for data block length before reading relavant DSC
bytes.

Signed-off-by: Ankit Nautiyal <ankit.k.nauti...@intel.com>
---
 drivers/gpu/drm/drm_edid.c | 93 ++++++++++++++++++++------------------
 1 file changed, 49 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index ffff1d08b3a4..c9c3a9c8fa26 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5706,9 +5706,6 @@ static void drm_parse_ycbcr420_deep_color_info(struct 
drm_connector *connector,
 static void drm_parse_dsc_info(struct drm_hdmi_dsc_cap *hdmi_dsc,
                               const u8 *hf_scds)
 {
-       u8 dsc_max_slices;
-       u8 dsc_max_frl_rate;
-
        hdmi_dsc->v_1p2 = hf_scds[11] & DRM_EDID_DSC_1P2;
 
        if (!hdmi_dsc->v_1p2)
@@ -5727,47 +5724,54 @@ static void drm_parse_dsc_info(struct drm_hdmi_dsc_cap 
*hdmi_dsc,
                /* Supports min 8 BPC if DSC1.2 is supported*/
                hdmi_dsc->bpc_supported = 8;
 
-       dsc_max_frl_rate = (hf_scds[12] & DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
-       drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
-                            &hdmi_dsc->max_frl_rate_per_lane);
-       hdmi_dsc->total_chunk_kbytes = hf_scds[13] & 
DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
+       if (cea_db_payload_len(hf_scds) >= 12 && hf_scds[12]) {
+               u8 dsc_max_slices;
+               u8 dsc_max_frl_rate;
 
-       dsc_max_slices = hf_scds[12] & DRM_EDID_DSC_MAX_SLICES;
+               dsc_max_frl_rate = (hf_scds[12] & 
DRM_EDID_DSC_MAX_FRL_RATE_MASK) >> 4;
+               drm_get_max_frl_rate(dsc_max_frl_rate, &hdmi_dsc->max_lanes,
+                                    &hdmi_dsc->max_frl_rate_per_lane);
 
-       switch (dsc_max_slices) {
-       case 1:
-               hdmi_dsc->max_slices = 1;
-               hdmi_dsc->clk_per_slice = 340;
-               break;
-       case 2:
-               hdmi_dsc->max_slices = 2;
-               hdmi_dsc->clk_per_slice = 340;
-               break;
-       case 3:
-               hdmi_dsc->max_slices = 4;
-               hdmi_dsc->clk_per_slice = 340;
-               break;
-       case 4:
-               hdmi_dsc->max_slices = 8;
-               hdmi_dsc->clk_per_slice = 340;
-               break;
-       case 5:
-               hdmi_dsc->max_slices = 8;
-               hdmi_dsc->clk_per_slice = 400;
-               break;
-       case 6:
-               hdmi_dsc->max_slices = 12;
-               hdmi_dsc->clk_per_slice = 400;
-               break;
-       case 7:
-               hdmi_dsc->max_slices = 16;
-               hdmi_dsc->clk_per_slice = 400;
-               break;
-       case 0:
-       default:
-               hdmi_dsc->max_slices = 0;
-               hdmi_dsc->clk_per_slice = 0;
+               dsc_max_slices = hf_scds[12] & DRM_EDID_DSC_MAX_SLICES;
+
+               switch (dsc_max_slices) {
+               case 1:
+                       hdmi_dsc->max_slices = 1;
+                       hdmi_dsc->clk_per_slice = 340;
+                       break;
+               case 2:
+                       hdmi_dsc->max_slices = 2;
+                       hdmi_dsc->clk_per_slice = 340;
+                       break;
+               case 3:
+                       hdmi_dsc->max_slices = 4;
+                       hdmi_dsc->clk_per_slice = 340;
+                       break;
+               case 4:
+                       hdmi_dsc->max_slices = 8;
+                       hdmi_dsc->clk_per_slice = 340;
+                       break;
+               case 5:
+                       hdmi_dsc->max_slices = 8;
+                       hdmi_dsc->clk_per_slice = 400;
+                       break;
+               case 6:
+                       hdmi_dsc->max_slices = 12;
+                       hdmi_dsc->clk_per_slice = 400;
+                       break;
+               case 7:
+                       hdmi_dsc->max_slices = 16;
+                       hdmi_dsc->clk_per_slice = 400;
+                       break;
+               case 0:
+               default:
+                       hdmi_dsc->max_slices = 0;
+                       hdmi_dsc->clk_per_slice = 0;
+               }
        }
+
+       if (cea_db_payload_len(hf_scds) >= 13 && hf_scds[13])
+               hdmi_dsc->total_chunk_kbytes = hf_scds[13] & 
DRM_EDID_DSC_TOTAL_CHUNK_KBYTES;
 }
 
 /* Sink Capability Data Structure */
@@ -5776,6 +5780,7 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
 {
        struct drm_display_info *display = &connector->display_info;
        struct drm_hdmi_info *hdmi = &display->hdmi;
+       struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
 
        display->has_hdmi_infoframe = true;
 
@@ -5816,17 +5821,17 @@ static void drm_parse_hdmi_forum_scds(struct 
drm_connector *connector,
 
        if (hf_scds[7]) {
                u8 max_frl_rate;
-               struct drm_hdmi_dsc_cap *hdmi_dsc = &hdmi->dsc_cap;
 
                DRM_DEBUG_KMS("hdmi_21 sink detected. parsing edid\n");
                max_frl_rate = (hf_scds[7] & DRM_EDID_MAX_FRL_RATE_MASK) >> 4;
                drm_get_max_frl_rate(max_frl_rate, &hdmi->max_lanes,
                                     &hdmi->max_frl_rate_per_lane);
-
-               drm_parse_dsc_info(hdmi_dsc, hf_scds);
        }
 
        drm_parse_ycbcr420_deep_color_info(connector, hf_scds);
+
+       if (cea_db_payload_len(hf_scds) >= 11 && hf_scds[11])
+               drm_parse_dsc_info(hdmi_dsc, hf_scds);
 }
 
 static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
-- 
2.25.1

Reply via email to