DF-4840 / fix.diff
--- 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; } |