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@who-t.net> Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
parent
541ab2ecd4
commit
564ccf2ce9
|
@ -58,8 +58,6 @@ extern void DeviceFocusEvent(DeviceIntPtr dev,
|
||||||
|
|
||||||
extern void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode);
|
extern void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode);
|
||||||
|
|
||||||
extern void LeaveWindow(DeviceIntPtr dev);
|
|
||||||
|
|
||||||
extern void CoreFocusEvent(DeviceIntPtr kbd,
|
extern void CoreFocusEvent(DeviceIntPtr kbd,
|
||||||
int type, int mode, int detail, WindowPtr pWin);
|
int type, int mode, int detail, WindowPtr pWin);
|
||||||
|
|
||||||
|
|
|
@ -335,4 +335,7 @@ union _InternalEvent {
|
||||||
GestureEvent gesture_event;
|
GestureEvent gesture_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern void
|
||||||
|
LeaveWindow(DeviceIntPtr dev);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -397,8 +397,21 @@ miPointerWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
|
||||||
#ifdef PANORAMIX
|
#ifdef PANORAMIX
|
||||||
&& noPanoramiXExtension
|
&& noPanoramiXExtension
|
||||||
#endif
|
#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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue