summaryrefslogtreecommitdiff
path: root/xserver
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2023-10-25 05:16:41 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2023-10-25 05:16:41 +0000
commit3fa480415b22a9a0bad6388bd24d62cfa3cb8090 (patch)
treeb121884ae3ac1a0f727193ea589dd051eab5d9af /xserver
parent6fab7f830fb5dcdce6072303c7a1b95d158d797f (diff)
Fix several input validation errors in the X server
CVE-2023-5367 CVE-2023-5380 CVE-2023-5574
Diffstat (limited to 'xserver')
-rw-r--r--xserver/Xi/xiproperty.c4
-rw-r--r--xserver/dix/enterleave.h2
-rw-r--r--xserver/fb/fb.h1
-rw-r--r--xserver/fb/fbscreen.c14
-rw-r--r--xserver/hw/vfb/InitOutput.c7
-rw-r--r--xserver/include/eventstr.h3
-rw-r--r--xserver/mi/mipointer.c17
-rw-r--r--xserver/mi/miscrinit.c2
-rw-r--r--xserver/randr/rrproperty.c4
9 files changed, 34 insertions, 20 deletions
diff --git a/xserver/Xi/xiproperty.c b/xserver/Xi/xiproperty.c
index 066ba21fb..d315f04d0 100644
--- a/xserver/Xi/xiproperty.c
+++ b/xserver/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/xserver/dix/enterleave.h b/xserver/dix/enterleave.h
index 4b833d8a3..e8af924c6 100644
--- a/xserver/dix/enterleave.h
+++ b/xserver/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/xserver/fb/fb.h b/xserver/fb/fb.h
index 8ab050d0f..404bca3c9 100644
--- a/xserver/fb/fb.h
+++ b/xserver/fb/fb.h
@@ -410,6 +410,7 @@ typedef struct {
#endif
DevPrivateKeyRec gcPrivateKeyRec;
DevPrivateKeyRec winPrivateKeyRec;
+ CloseScreenProcPtr CloseScreen;
} FbScreenPrivRec, *FbScreenPrivPtr;
#define fbGetScreenPrivate(pScreen) ((FbScreenPrivPtr) \
diff --git a/xserver/fb/fbscreen.c b/xserver/fb/fbscreen.c
index 4ab807ab5..c481033f9 100644
--- a/xserver/fb/fbscreen.c
+++ b/xserver/fb/fbscreen.c
@@ -29,6 +29,7 @@
Bool
fbCloseScreen(ScreenPtr pScreen)
{
+ FbScreenPrivPtr screen_priv = fbGetScreenPrivate(pScreen);
int d;
DepthPtr depths = pScreen->allowedDepths;
@@ -37,9 +38,10 @@ fbCloseScreen(ScreenPtr pScreen)
free(depths[d].vids);
free(depths);
free(pScreen->visuals);
- if (pScreen->devPrivate)
- FreePixmap((PixmapPtr)pScreen->devPrivate);
- return TRUE;
+
+ pScreen->CloseScreen = screen_priv->CloseScreen;
+
+ return pScreen->CloseScreen(pScreen);
}
Bool
@@ -144,6 +146,7 @@ fbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
int dpix, int dpiy, int width, int bpp)
#endif
{
+ FbScreenPrivPtr screen_priv;
VisualPtr visuals;
DepthPtr depths;
int nvisuals;
@@ -177,8 +180,11 @@ fbFinishScreenInit(ScreenPtr pScreen, void *pbits, int xsize, int ysize,
rootdepth, ndepths, depths,
defaultVisual, nvisuals, visuals))
return FALSE;
- /* overwrite miCloseScreen with our own */
+
+ screen_priv = fbGetScreenPrivate(pScreen);
+ screen_priv->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = fbCloseScreen;
+
return TRUE;
}
diff --git a/xserver/hw/vfb/InitOutput.c b/xserver/hw/vfb/InitOutput.c
index 01e08cca0..08158fbbc 100644
--- a/xserver/hw/vfb/InitOutput.c
+++ b/xserver/hw/vfb/InitOutput.c
@@ -727,13 +727,6 @@ vfbCloseScreen(ScreenPtr pScreen)
pScreen->CloseScreen = pvfb->closeScreen;
- /*
- * fb overwrites miCloseScreen, so do this here
- */
- if (pScreen->devPrivate)
- (*pScreen->DestroyPixmap) (pScreen->devPrivate);
- pScreen->devPrivate = NULL;
-
return pScreen->CloseScreen(pScreen);
}
diff --git a/xserver/include/eventstr.h b/xserver/include/eventstr.h
index 93308f9b2..a9926eaee 100644
--- a/xserver/include/eventstr.h
+++ b/xserver/include/eventstr.h
@@ -335,4 +335,7 @@ union _InternalEvent {
GestureEvent gesture_event;
};
+extern void
+LeaveWindow(DeviceIntPtr dev);
+
#endif
diff --git a/xserver/mi/mipointer.c b/xserver/mi/mipointer.c
index a638f25d4..8cf003514 100644
--- a/xserver/mi/mipointer.c
+++ b/xserver/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);
+ }
}
/**
diff --git a/xserver/mi/miscrinit.c b/xserver/mi/miscrinit.c
index 3bb52b1bc..b88938c9a 100644
--- a/xserver/mi/miscrinit.c
+++ b/xserver/mi/miscrinit.c
@@ -249,10 +249,10 @@ miScreenInit(ScreenPtr pScreen, void *pbits, /* pointer to screen bits */
pScreen->numVisuals = numVisuals;
pScreen->visuals = visuals;
if (width) {
+ pScreen->CloseScreen = miCloseScreen;
#ifdef MITSHM
ShmRegisterFbFuncs(pScreen);
#endif
- pScreen->CloseScreen = miCloseScreen;
}
/* else CloseScreen */
/* QueryBestSize */
diff --git a/xserver/randr/rrproperty.c b/xserver/randr/rrproperty.c
index c2fb9585c..25469f57b 100644
--- a/xserver/randr/rrproperty.c
+++ b/xserver/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)