|
|
031995 |
From 004f461c440cb6611eefb48fbbb4fa53a6d49f80 Mon Sep 17 00:00:00 2001
|
|
|
031995 |
From: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
031995 |
Date: Thu, 5 Oct 2023 12:19:45 +1000
|
|
|
031995 |
Subject: [PATCH xserver 2/4] mi: reset the PointerWindows reference on screen
|
|
|
031995 |
switch
|
|
|
031995 |
|
|
|
031995 |
PointerWindows[] keeps a reference to the last window our sprite
|
|
|
031995 |
entered - changes are usually handled by CheckMotion().
|
|
|
031995 |
|
|
|
031995 |
If we switch between screens via XWarpPointer our
|
|
|
031995 |
dev->spriteInfo->sprite->win is set to the new screen's root window.
|
|
|
031995 |
If there's another window at the cursor location CheckMotion() will
|
|
|
031995 |
trigger the right enter/leave events later. If there is not, it skips
|
|
|
031995 |
that process and we never trigger LeaveWindow() - PointerWindows[] for
|
|
|
031995 |
the device still refers to the previous window.
|
|
|
031995 |
|
|
|
031995 |
If that window is destroyed we have a dangling reference that will
|
|
|
031995 |
eventually cause a use-after-free bug when checking the window hierarchy
|
|
|
031995 |
later.
|
|
|
031995 |
|
|
|
031995 |
To trigger this, we require:
|
|
|
031995 |
- two protocol screens
|
|
|
031995 |
- XWarpPointer to the other screen's root window
|
|
|
031995 |
- XDestroyWindow before entering any other window
|
|
|
031995 |
|
|
|
031995 |
This is a niche bug so we hack around it by making sure we reset the
|
|
|
031995 |
PointerWindows[] entry so we cannot have a dangling pointer. This
|
|
|
031995 |
doesn't handle Enter/Leave events correctly but the previous code didn't
|
|
|
031995 |
either.
|
|
|
031995 |
|
|
|
031995 |
CVE-2023-5380, ZDI-CAN-21608
|
|
|
031995 |
|
|
|
031995 |
This vulnerability was discovered by:
|
|
|
031995 |
Sri working with Trend Micro Zero Day Initiative
|
|
|
031995 |
|
|
|
031995 |
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
031995 |
Reviewed-by: Adam Jackson <ajax@redhat.com>
|
|
|
031995 |
---
|
|
|
031995 |
dix/enterleave.h | 2 --
|
|
|
031995 |
include/eventstr.h | 3 +++
|
|
|
031995 |
mi/mipointer.c | 17 +++++++++++++++--
|
|
|
031995 |
3 files changed, 18 insertions(+), 4 deletions(-)
|
|
|
031995 |
|
|
|
031995 |
diff --git a/dix/enterleave.h b/dix/enterleave.h
|
|
|
031995 |
index 4b833d8a3b..e8af924c68 100644
|
|
|
031995 |
--- a/dix/enterleave.h
|
|
|
031995 |
+++ b/dix/enterleave.h
|
|
|
031995 |
@@ -58,8 +58,6 @@ extern void DeviceFocusEvent(DeviceIntPtr dev,
|
|
|
031995 |
|
|
|
031995 |
extern void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode);
|
|
|
031995 |
|
|
|
031995 |
-extern void LeaveWindow(DeviceIntPtr dev);
|
|
|
031995 |
-
|
|
|
031995 |
extern void CoreFocusEvent(DeviceIntPtr kbd,
|
|
|
031995 |
int type, int mode, int detail, WindowPtr pWin);
|
|
|
031995 |
|
|
|
031995 |
diff --git a/include/eventstr.h b/include/eventstr.h
|
|
|
031995 |
index bf3b95fe4a..2bae3b0767 100644
|
|
|
031995 |
--- a/include/eventstr.h
|
|
|
031995 |
+++ b/include/eventstr.h
|
|
|
031995 |
@@ -296,4 +296,7 @@ union _InternalEvent {
|
|
|
031995 |
#endif
|
|
|
031995 |
};
|
|
|
031995 |
|
|
|
031995 |
+extern void
|
|
|
031995 |
+LeaveWindow(DeviceIntPtr dev);
|
|
|
031995 |
+
|
|
|
031995 |
#endif
|
|
|
031995 |
diff --git a/mi/mipointer.c b/mi/mipointer.c
|
|
|
031995 |
index 75be1aeeb8..b12ae9be1d 100644
|
|
|
031995 |
--- a/mi/mipointer.c
|
|
|
031995 |
+++ b/mi/mipointer.c
|
|
|
031995 |
@@ -397,8 +397,21 @@ miPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
|
|
|
031995 |
#ifdef PANORAMIX
|
|
|
031995 |
&& noPanoramiXExtension
|
|
|
031995 |
#endif
|
|
|
031995 |
- )
|
|
|
031995 |
- UpdateSpriteForScreen(pDev, pScreen);
|
|
|
031995 |
+ ) {
|
|
|
031995 |
+ DeviceIntPtr master = GetMaster(pDev, MASTER_POINTER);
|
|
|
031995 |
+ /* Hack for CVE-2023-5380: if we're moving
|
|
|
031995 |
+ * screens PointerWindows[] keeps referring to the
|
|
|
031995 |
+ * old window. If that gets destroyed we have a UAF
|
|
|
031995 |
+ * bug later. Only happens when jumping from a window
|
|
|
031995 |
+ * to the root window on the other screen.
|
|
|
031995 |
+ * Enter/Leave events are incorrect for that case but
|
|
|
031995 |
+ * too niche to fix.
|
|
|
031995 |
+ */
|
|
|
031995 |
+ LeaveWindow(pDev);
|
|
|
031995 |
+ if (master)
|
|
|
031995 |
+ LeaveWindow(master);
|
|
|
031995 |
+ UpdateSpriteForScreen(pDev, pScreen);
|
|
|
031995 |
+ }
|
|
|
031995 |
}
|
|
|
031995 |
|
|
|
031995 |
/**
|
|
|
031995 |
--
|
|
|
031995 |
2.41.0
|
|
|
031995 |
|