⬢ DragonFlyBSD Kernel Audit
DF-4678 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/i915/i915_gem_stolen.c
+++ b/sys/dev/drm/i915/i915_gem_stolen.c
@@ -88,14 +88,28 @@
 	static struct rman stolen_rman;
 	struct linux_resource *res;
 
-	stolen_rman.rm_start = start;
-	stolen_rman.rm_end = start + n;
-	stolen_rman.rm_type = RMAN_ARRAY;
-	stolen_rman.rm_descr = name;
-	if (rman_init(&stolen_rman, -1))
-		return NULL;
-
-	if (rman_manage_region(&stolen_rman, stolen_rman.rm_start, stolen_rman.rm_end))
+	/*
+	 * NB: this shim cannot provide the Linux devm conflict check
+	 * against other drivers; it only keeps driver-local bookkeeping.
+	 * Initialize the static rman once (a second rman_init() would
+	 * re-insert it into the global rman_head and leak the old lock),
+	 * and use inclusive end bounds (rman ranges are [start, end]).
+	 */
+	static int stolen_rman_inited;
+
+	if (!stolen_rman_inited) {
+		stolen_rman.rm_start = start;
+		stolen_rman.rm_end = start + n - 1;
+		stolen_rman.rm_type = RMAN_ARRAY;
+		stolen_rman.rm_descr = name;
+		if (rman_init(&stolen_rman, -1))
+			return NULL;
+		stolen_rman_inited = 1;
+	}
+
+	if (n == 0 || start + n - 1 < start)
+		return NULL;
+	if (rman_manage_region(&stolen_rman, start, start + n - 1))
 		return NULL;
 
 	res = kmalloc(sizeof(*res), M_DRM, GFP_KERNEL);