]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Thu, 4 Jul 2019 00:11:03 +0000 (20:11 -0400)
committerSasha Levin <sashal@kernel.org>
Thu, 4 Jul 2019 00:11:03 +0000 (20:11 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.19/drm-i915-dmc-protect-against-reading-random-memory.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/drm-i915-dmc-protect-against-reading-random-memory.patch b/queue-4.19/drm-i915-dmc-protect-against-reading-random-memory.patch
new file mode 100644 (file)
index 0000000..8e61d06
--- /dev/null
@@ -0,0 +1,99 @@
+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
+
index c4fc0e41d661d71fc9390c02e90929d9820c5c8d..fa12e4d87afdfdf8be992d80c84b9dd2aee82e2e 100644 (file)
@@ -37,3 +37,4 @@ mm-mlock.c-change-count_mm_mlocked_page_nr-return-ty.patch
 tracing-avoid-build-warning-with-have_nop_mcount.patch
 module-fix-livepatch-ftrace-module-text-permissions-.patch
 ftrace-fix-null-pointer-dereference-in-free_ftrace_f.patch
+drm-i915-dmc-protect-against-reading-random-memory.patch