From 1b1b9ff35f8d61743a72db84edefedc1f955f7d6 Mon Sep 17 00:00:00 2001
From: Denis Kirjanov <denis.kirjanov@suse.com>
Date: Jan 30 2024 13:27:41 +0000
Subject: Merge branch 'users/pjakobsson/cve/linux-4.12/for-next' into cve/linux-4.12


Pull DRM fixes from Patrik Jakobsson

---

diff --git a/patches.suse/drm-atomic-Fix-potential-use-after-free-in-nonblocki.patch b/patches.suse/drm-atomic-Fix-potential-use-after-free-in-nonblocki.patch
new file mode 100644
index 0000000..6510a4e
--- /dev/null
+++ b/patches.suse/drm-atomic-Fix-potential-use-after-free-in-nonblocki.patch
@@ -0,0 +1,90 @@
+From 4e076c73e4f6e90816b30fcd4a0d7ab365087255 Mon Sep 17 00:00:00 2001
+From: Daniel Vetter <daniel.vetter@ffwll.ch>
+Date: Fri, 21 Jul 2023 15:58:38 +0200
+Subject: drm/atomic: Fix potential use-after-free in nonblocking commits
+Git-commit: 4e076c73e4f6e90816b30fcd4a0d7ab365087255
+Patch-mainline: v6.5-rc3
+References: bsc#1219120 CVE-2023-51043
+
+This requires a bit of background.  Properly done a modeset driver's
+unload/remove sequence should be
+
+	drm_dev_unplug();
+	drm_atomic_helper_shutdown();
+	drm_dev_put();
+
+The trouble is that the drm_dev_unplugged() checks are by design racy,
+they do not synchronize against all outstanding ioctl.  This is because
+those ioctl could block forever (both for modeset and for driver
+specific ioctls), leading to deadlocks in hotunplug.  Instead the code
+sections that touch the hardware need to be annotated with
+drm_dev_enter/exit, to avoid accessing hardware resources after the
+unload/remove has finished.
+
+To avoid use-after-free issues all the involved userspace visible
+objects are supposed to hold a reference on the underlying drm_device,
+like drm_file does.
+
+The issue now is that we missed one, the atomic modeset ioctl can be run
+in a nonblocking fashion, and in that case it cannot rely on the implied
+drm_device reference provided by the ioctl calling context.  This can
+result in a use-after-free if an nonblocking atomic commit is carefully
+raced against a driver unload.
+
+Fix this by unconditionally grabbing a drm_device reference for any
+drm_atomic_state structures.  Strictly speaking this isn't required for
+blocking commits and TEST_ONLY calls, but it's the simpler approach.
+
+Thanks to shanzhulig for the initial idea of grabbing an unconditional
+reference, I just added comments, a condensed commit message and fixed a
+minor potential issue in where exactly we drop the final reference.
+
+Reported-by: shanzhulig <shanzhulig@gmail.com>
+Suggested-by: shanzhulig <shanzhulig@gmail.com>
+Reviewed-by: Maxime Ripard <mripard@kernel.org>
+Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Cc: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: David Airlie <airlied@gmail.com>
+Cc: stable@kernel.org
+Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
+---
+ drivers/gpu/drm/drm_atomic.c |   11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/drm_atomic.c
++++ b/drivers/gpu/drm/drm_atomic.c
+@@ -88,6 +88,12 @@
+ 	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_ref(dev);
+ 	state->dev = dev;
+ 
+ 	DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
+@@ -244,7 +250,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);
+ 
+@@ -256,6 +263,8 @@
+ 		drm_atomic_state_default_release(state);
+ 		kfree(state);
+ 	}
++
++	drm_dev_unref(dev);
+ }
+ EXPORT_SYMBOL(__drm_atomic_state_free);
+ 
diff --git a/series.conf b/series.conf
index 0b6c09f..cffbba5 100644
--- a/series.conf
+++ b/series.conf
@@ -26939,6 +26939,7 @@
 	patches.suse/netfilter-nf_tables-prevent-OOB-access-in-nft_byteor.patch
 	patches.suse/net-sched-cls_fw-Fix-improper-refcount-update-leads-.patch
 	patches.suse/net-sched-sch_qfq-account-for-stab-overhead-in-qfq_e.patch
+	patches.suse/drm-atomic-Fix-potential-use-after-free-in-nonblocki.patch
 	patches.suse/tcp-Reduce-chance-of-collisions-in-inet6_hashfn.patch
 	patches.suse/0001-net-sched-cls_u32-No-longer-copy-tcf_result-on-updat.patch
 	patches.suse/0002-net-sched-cls_fw-No-longer-copy-tcf_result-on-update.patch