--- /dev/null
+From 3142bd0b9818d37a07268922a6da7ec92ca11aab Mon Sep 17 00:00:00 2001
+From: Lucas De Marchi <lucas.demarchi@intel.com>
+Date: Tue, 2 Jul 2019 12:23:04 -0700
+Subject: drm/i915/dmc: protect against reading random memory
+
+commit bc7b488b1d1c71dc4c5182206911127bc6c410d6 upstream.
+
+While loading the DMC firmware we were double checking the headers made
+sense, but in no place we checked that we were actually reading memory
+we were supposed to. This could be wrong in case the firmware file is
+truncated or malformed.
+
+Before this patch:
+ # ls -l /lib/firmware/i915/icl_dmc_ver1_07.bin
+ -rw-r--r-- 1 root root 25716 Feb 1 12:26 icl_dmc_ver1_07.bin
+ # truncate -s 25700 /lib/firmware/i915/icl_dmc_ver1_07.bin
+ # modprobe i915
+ # dmesg| grep -i dmc
+ [drm:intel_csr_ucode_init [i915]] Loading i915/icl_dmc_ver1_07.bin
+ [drm] Finished loading DMC firmware i915/icl_dmc_ver1_07.bin (v1.7)
+
+i.e. it loads random data. Now it fails like below:
+ [drm:intel_csr_ucode_init [i915]] Loading i915/icl_dmc_ver1_07.bin
+ [drm:csr_load_work_fn [i915]] *ERROR* Truncated DMC firmware, rejecting.
+ i915 0000:00:02.0: Failed to load DMC firmware i915/icl_dmc_ver1_07.bin. Disabling runtime power management.
+ i915 0000:00:02.0: DMC firmware homepage: https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/i915
+
+Before reading any part of the firmware file, validate the input first.
+
+Fixes: eb805623d8b1 ("drm/i915/skl: Add support to load SKL CSR firmware.")
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20190605235535.17791-1-lucas.demarchi@intel.com
+(cherry picked from commit bc7b488b1d1c71dc4c5182206911127bc6c410d6)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+[ Lucas: backported to 4.9+ adjusting the context ]
+Cc: stable@vger.kernel.org # v4.9+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/intel_csr.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c
+index cf9b600cca79..ca1a578d790d 100644
+--- a/drivers/gpu/drm/i915/intel_csr.c
++++ b/drivers/gpu/drm/i915/intel_csr.c
+@@ -282,10 +282,17 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
+ uint32_t i;
+ uint32_t *dmc_payload;
+ uint32_t required_version;
++ size_t fsize;
+
+ if (!fw)
+ return NULL;
+
++ fsize = sizeof(struct intel_css_header) +
++ sizeof(struct intel_package_header) +
++ sizeof(struct intel_dmc_header);
++ if (fsize > fw->size)
++ goto error_truncated;
++
+ /* Extract CSS Header information*/
+ css_header = (struct intel_css_header *)fw->data;
+ if (sizeof(struct intel_css_header) !=
+@@ -360,6 +367,9 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
+ return NULL;
+ }
+ readcount += dmc_offset;
++ fsize += dmc_offset;
++ if (fsize > fw->size)
++ goto error_truncated;
+
+ /* Extract dmc_header information. */
+ dmc_header = (struct intel_dmc_header *)&fw->data[readcount];
+@@ -391,6 +401,10 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
+
+ /* fw_size is in dwords, so multiplied by 4 to convert into bytes. */
+ nbytes = dmc_header->fw_size * 4;
++ fsize += nbytes;
++ if (fsize > fw->size)
++ goto error_truncated;
++
+ if (nbytes > CSR_MAX_FW_SIZE) {
+ DRM_ERROR("DMC firmware too big (%u bytes)\n", nbytes);
+ return NULL;
+@@ -404,6 +418,10 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv,
+ }
+
+ return memcpy(dmc_payload, &fw->data[readcount], nbytes);
++
++error_truncated:
++ DRM_ERROR("Truncated DMC firmware, rejecting.\n");
++ return NULL;
+ }
+
+ static void csr_load_work_fn(struct work_struct *work)
+--
+2.20.1
+