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