xserver: Branch 'server-21.1-branch' - 2 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Oct 25 01:01:22 UTC 2023


 Xi/xiproperty.c    |    4 ++--
 dix/enterleave.h   |    2 --
 include/eventstr.h |    3 +++
 mi/mipointer.c     |   17 +++++++++++++++--
 randr/rrproperty.c |    4 ++--
 5 files changed, 22 insertions(+), 8 deletions(-)

New commits:
commit 3e290b3c7c3018acf1f08979d014fe3941c94f84
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Oct 5 12:19:45 2023 +1000

    mi: reset the PointerWindows reference on screen switch
    
    PointerWindows[] keeps a reference to the last window our sprite
    entered - changes are usually handled by CheckMotion().
    
    If we switch between screens via XWarpPointer our
    dev->spriteInfo->sprite->win is set to the new screen's root window.
    If there's another window at the cursor location CheckMotion() will
    trigger the right enter/leave events later. If there is not, it skips
    that process and we never trigger LeaveWindow() - PointerWindows[] for
    the device still refers to the previous window.
    
    If that window is destroyed we have a dangling reference that will
    eventually cause a use-after-free bug when checking the window hierarchy
    later.
    
    To trigger this, we require:
    - two protocol screens
    - XWarpPointer to the other screen's root window
    - XDestroyWindow before entering any other window
    
    This is a niche bug so we hack around it by making sure we reset the
    PointerWindows[] entry so we cannot have a dangling pointer. This
    doesn't handle Enter/Leave events correctly but the previous code didn't
    either.
    
    CVE-2023-5380, ZDI-CAN-21608
    
    This vulnerability was discovered by:
    Sri working with Trend Micro Zero Day Initiative
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    (cherry picked from commit 564ccf2ce9616620456102727acb8b0256b7bbd7)

diff --git a/dix/enterleave.h b/dix/enterleave.h
index 4b833d8a3..e8af924c6 100644
--- a/dix/enterleave.h
+++ b/dix/enterleave.h
@@ -58,8 +58,6 @@ extern void DeviceFocusEvent(DeviceIntPtr dev,
 
 extern void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode);
 
-extern void LeaveWindow(DeviceIntPtr dev);
-
 extern void CoreFocusEvent(DeviceIntPtr kbd,
                            int type, int mode, int detail, WindowPtr pWin);
 
diff --git a/include/eventstr.h b/include/eventstr.h
index 93308f9b2..a9926eaee 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -335,4 +335,7 @@ union _InternalEvent {
     GestureEvent gesture_event;
 };
 
+extern void
+LeaveWindow(DeviceIntPtr dev);
+
 #endif
diff --git a/mi/mipointer.c b/mi/mipointer.c
index a638f25d4..8cf003514 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -397,8 +397,21 @@ miPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
 #ifdef PANORAMIX
         && noPanoramiXExtension
 #endif
-        )
-        UpdateSpriteForScreen(pDev, pScreen);
+        ) {
+            DeviceIntPtr master = GetMaster(pDev, MASTER_POINTER);
+            /* Hack for CVE-2023-5380: if we're moving
+             * screens PointerWindows[] keeps referring to the
+             * old window. If that gets destroyed we have a UAF
+             * bug later. Only happens when jumping from a window
+             * to the root window on the other screen.
+             * Enter/Leave events are incorrect for that case but
+             * too niche to fix.
+             */
+            LeaveWindow(pDev);
+            if (master)
+                LeaveWindow(master);
+            UpdateSpriteForScreen(pDev, pScreen);
+    }
 }
 
 /**
commit f2922f6ffa871b0d549878303ca09bc53cdadcf8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Oct 3 11:53:05 2023 +1000

    Xi/randr: fix handling of PropModeAppend/Prepend
    
    The handling of appending/prepending properties was incorrect, with at
    least two bugs: the property length was set to the length of the new
    part only, i.e. appending or prepending N elements to a property with P
    existing elements always resulted in the property having N elements
    instead of N + P.
    
    Second, when pre-pending a value to a property, the offset for the old
    values was incorrect, leaving the new property with potentially
    uninitalized values and/or resulting in OOB memory writes.
    For example, prepending a 3 element value to a 5 element property would
    result in this 8 value array:
      [N, N, N, ?, ?, P, P, P ] P, P
                                ^OOB write
    
    The XI2 code is a copy/paste of the RandR code, so the bug exists in
    both.
    
    CVE-2023-5367, ZDI-CAN-22153
    
    This vulnerability was discovered by:
    Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 541ab2ecd41d4d8689e71855d93e492bc554719a)

diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 066ba21fb..d315f04d0 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -730,7 +730,7 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
                 XIDestroyDeviceProperty(prop);
             return BadAlloc;
         }
-        new_value.size = len;
+        new_value.size = total_len;
         new_value.type = type;
         new_value.format = format;
 
@@ -747,7 +747,7 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type,
         case PropModePrepend:
             new_data = new_value.data;
             old_data = (void *) (((char *) new_value.data) +
-                                  (prop_value->size * size_in_bytes));
+                                  (len * size_in_bytes));
             break;
         }
         if (new_data)
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
index c2fb9585c..25469f57b 100644
--- a/randr/rrproperty.c
+++ b/randr/rrproperty.c
@@ -209,7 +209,7 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
                 RRDestroyOutputProperty(prop);
             return BadAlloc;
         }
-        new_value.size = len;
+        new_value.size = total_len;
         new_value.type = type;
         new_value.format = format;
 
@@ -226,7 +226,7 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type,
         case PropModePrepend:
             new_data = new_value.data;
             old_data = (void *) (((char *) new_value.data) +
-                                  (prop_value->size * size_in_bytes));
+                                  (len * size_in_bytes));
             break;
         }
         if (new_data)


More information about the xorg-commit mailing list