drm/atomic: Fix potential use-after-free in nonblocking commits
authorjsg <jsg@openbsd.org>
Wed, 26 Jul 2023 11:06:51 +0000 (11:06 +0000)
committerjsg <jsg@openbsd.org>
Wed, 26 Jul 2023 11:06:51 +0000 (11:06 +0000)
From Daniel Vetter
e4a0e09b79bd2c0895c508cdc5e0265a083cc05d in linux-6.1.y/6.1.40
4e076c73e4f6e90816b30fcd4a0d7ab365087255 in mainline linux

sys/dev/pci/drm/drm_atomic.c

index 5b1afb8..b876b2d 100644 (file)
@@ -140,6 +140,12 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
        if (!state->planes)
                goto fail;
 
+       /*
+        * Because drm_atomic_state can be committed asynchronously we need our
+        * own reference and cannot rely on the on implied by drm_file in the
+        * ioctl call.
+        */
+       drm_dev_get(dev);
        state->dev = dev;
 
        drm_dbg_atomic(dev, "Allocated atomic state %p\n", state);
@@ -299,7 +305,8 @@ EXPORT_SYMBOL(drm_atomic_state_clear);
 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);
 
@@ -311,6 +318,8 @@ void __drm_atomic_state_free(struct kref *ref)
                drm_atomic_state_default_release(state);
                kfree(state);
        }
+
+       drm_dev_put(dev);
 }
 EXPORT_SYMBOL(__drm_atomic_state_free);