⬢ DragonFlyBSD Kernel Audit
DF-4840 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/drm_mode_object.c
+++ b/sys/dev/drm/drm_mode_object.c
@@ -512,9 +512,20 @@
 	if (!drm_core_check_feature(dev, DRIVER_MODESET))
 		return -EOPNOTSUPP;
 
+	/* DF-4840: mode objects of types with no free_cb (MODE, and at
+	 * driver-teardown CRTC/PLANE/PROPERTY) are handed out by
+	 * drm_mode_object_find() with no reference.  drm_mode_destroy()
+	 * runs under mode_config.mutex from connector reprobes, so the
+	 * lookup and every use of the object must hold the same mutex.
+	 * mode_config.mutex is LK_CANRECURSE, so the nested acquisition
+	 * through set_property_legacy()'s drm_modeset_lock_all() is safe.
+	 */
+	mutex_lock(&dev->mode_config.mutex);
 	arg_obj = drm_mode_object_find(dev, file_priv, arg->obj_id, arg->obj_type);
-	if (!arg_obj)
+	if (!arg_obj) {
+		mutex_unlock(&dev->mode_config.mutex);
 		return -ENOENT;
+	}
 
 	if (!arg_obj->properties)
 		goto out_unref;
@@ -530,5 +541,6 @@
 
 out_unref:
 	drm_mode_object_put(arg_obj);
+	mutex_unlock(&dev->mode_config.mutex);
 	return ret;
 }