⬢ DragonFlyBSD Kernel Audit
DF-3682 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/drm/drm_modes.c b/sys/dev/drm/drm_modes.c
index 1a2b3c4..5d6e7f8 100644
--- a/sys/dev/drm/drm_modes.c
+++ b/sys/dev/drm/drm_modes.c
@@ -479,6 +479,14 @@ drm_gtf_mode_complex(struct drm_device *dev, int hdisplay, int vdisplay,
 	/* 18.Find the ideal blanking duty cycle from blanking duty cycle */
 	ideal_duty_cycle = GTF_C_PRIME * 1000 -
 				(GTF_M_PRIME * 1000000 / hfreq_est);
+
+	/*
+	 * DF-3682: GTF_M/GTF_2C/GTF_K/GTF_2J come straight from a sink-
+	 * supplied EDID range-limit descriptor (drm_edid.c drm_gtf2_*).
+	 * Degenerate parameters (e.g. M=0 with C'=100) make
+	 * ideal_duty_cycle exactly 100000, driving the divisor below to
+	 * zero -> kernel divide error (#DE) -> panic.  Reject anything
+	 * that cannot yield a sane blanking duty cycle instead.
+	 */
+	if (ideal_duty_cycle <= 0 || ideal_duty_cycle >= 100000) {
+		drm_mode_destroy(dev, drm_mode);
+		return NULL;
+	}
 	/* 19.Find the number of pixels in the blanking time to the nearest
 	 * double character cell: */
 	hblank = total_active_pixels * ideal_duty_cycle /