DragonFlyBSD Kernel Audit
DF-1895 / fix.diff
← back to finding ↓ download raw
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);
 }