⬢ DragonFlyBSD Kernel Audit
DF-4122 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/i915/intel_bios.c
+++ b/sys/dev/drm/i915/intel_bios.c
@@ -562,6 +562,13 @@ parse_edp(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
 	edp = find_section(bdb, BDB_EDP);
 	if (!edp)
 		return;
+
+	/* fields through fast_link_params[] are read unconditionally */
+	if (get_blocksize(edp) < sizeof(edp->power_seqs) +
+	    sizeof(edp->color_depth) + sizeof(edp->fast_link_params)) {
+		DRM_DEBUG_KMS("BDB_EDP block too small (%u)\n", get_blocksize(edp));
+		return;
+	}
 
 	switch ((edp->color_depth >> (panel_type * 2)) & 3) {
@@ -675,6 +682,12 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
 		return;
 	}
 
+	if (get_blocksize(psr) < sizeof(*psr)) {
+		DRM_DEBUG_KMS("BDB_PSR block too small (%u)\n", get_blocksize(psr));
+		return;
+	}
+
 	psr_table = &psr->psr_table[panel_type];
@@ -307,6 +307,13 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv,
 	if (!backlight_data)
 		return;
 
+	/* data[16] + level[16] are read below regardless of BDB version */
+	if (get_blocksize(backlight_data) < 1 + sizeof(backlight_data->data) +
+	    sizeof(backlight_data->level)) {
+		DRM_DEBUG_KMS("BDB_LVDS_BACKLIGHT block too small (%u)\n",
+			      get_blocksize(backlight_data));
+		return;
+	}
+
 	if (backlight_data->entry_size != sizeof(backlight_data->data[0])) {
# NOTE: authored against the read-only sys/ tree after verification; never applied there.