From d207c176d3404e2c76c631521b7f39e21c939c11 Mon Sep 17 00:00:00 2001 From: Jonathan Gray Date: Thu, 11 Jul 2019 01:43:21 +0000 Subject: drm/i915/dmc: protect against reading random memory From Lucas De Marchi 600d3712ae122be3ceab0d7ac8246caa3d87dcea in linux 4.19.y/4.19.58 bc7b488b1d1c71dc4c5182206911127bc6c410d6 in mainline linux --- sys/dev/pci/drm/i915/intel_csr.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sys/dev/pci/drm/i915/intel_csr.c b/sys/dev/pci/drm/i915/intel_csr.c index f848e6962a1..093ae21c723 100644 --- a/sys/dev/pci/drm/i915/intel_csr.c +++ b/sys/dev/pci/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) -- cgit v1.2.3