⬢ DragonFlyBSD Kernel Audit
DF-4439 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/drm_atomic.c
+++ b/sys/dev/drm/drm_atomic.c
@@ -92,6 +92,15 @@
 	if (!state->planes)
 		goto fail;
 
+	/*
+	 * Because drm_atomic_state can be committed asynchronously we need
+	 * our own reference and cannot rely on the one implied by drm_file
+	 * in the ioctl call.
+	 *
+	 * Backport of Linux commit 4e076c73e4f6 ("drm/atomic: Fix potential
+	 * use-after-free in nonblocking commits").
+	 */
+	drm_dev_get(dev);
 	state->dev = dev;
 
 	DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
@@ -251,7 +260,8 @@
 void __drm_atomic_state_free(struct kref *ref)
 {
 	struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
-	struct drm_mode_config *config = &state->dev->mode_config;
+	struct drm_device *dev = state->dev;
+	struct drm_mode_config *config = &dev->mode_config;
 
 	drm_atomic_state_clear(state);
 
@@ -263,6 +273,8 @@
 		drm_atomic_state_default_release(state);
 		kfree(state);
 	}
+
+	drm_dev_put(dev);
 }
 EXPORT_SYMBOL(__drm_atomic_state_free);