diff --git a/sys/dev/drm/i915/intel_csr.c b/sys/dev/drm/i915/intel_csr.c --- a/sys/dev/drm/i915/intel_csr.c +++ b/sys/dev/drm/i915/intel_csr.c @@ -285,6 +285,7 @@ struct intel_csr *csr = &dev_priv->csr; const struct stepping_info *si = intel_get_stepping_info(dev_priv); uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes; + uint32_t fwsize; uint32_t max_fw_size = 0; uint32_t i; uint32_t *dmc_payload; @@ -293,6 +294,14 @@ if (!fw) return NULL; + fwsize = fw->datasize; + + /* Reject firmware too short to even hold the headers we index. */ + if (fwsize < sizeof(struct intel_css_header) + + sizeof(struct intel_package_header) + + sizeof(struct intel_dmc_header)) + return NULL; + /* Extract CSS Header information*/ css_header = (struct intel_css_header *)fw->data; if (sizeof(struct intel_css_header) != @@ -422,6 +431,8 @@ return NULL; } + if (readcount + nbytes > fwsize) + return NULL; return memcpy(dmc_payload, &fw->data[readcount], nbytes); }