dix: ensure that event fix-up is not performed on core events
Some checks are pending
Build X servers / xserver-build-ubuntu (push) Waiting to run
Build X servers / drivers-build-ubuntu (push) Waiting to run
Build X servers / xserver-build-mingw32-ubuntu (push) Waiting to run
Build X servers / xserver-build-macos (push) Waiting to run
Build X servers / xserver-build-freebsd (push) Waiting to run
Build X servers / xserver-build-dragonflybsd (push) Waiting to run
Build X servers / Release pushed tag (push) Blocked by required conditions
check PRs for merge conflicts / notify (push) Waiting to run
delete old workflow runs / delete_old_workflow_runs (push) Waiting to run
delete old workflow runs / purge_deleted_branch_workflows (push) Waiting to run

CoreEnterLeaveEvent calls FixUpEventFromWindow with a pointer to a stack-allocated xEvent structure, which may get later casted into an xXIDeviceEvent*, with writes done by FixUpXI2DeviceEventFromWindow at an offset larger than sizeof(xEvent). This code-path is protected by xi2_get_type() but the following warning is generated by building with -O3 and LTO:

In function 'FixUpXI2DeviceEventFromWindow',
    inlined from 'FixUpEventFromWindow' at ../dix/events.c:2716:13,
    inlined from 'CoreEnterLeaveEvent' at ../dix/events.c:4679:5:
../dix/events.c:2628:48: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
 2628 |         ((xXIEnterEvent *) event)->same_screen =
      |                                                ^
../dix/events.c: In function 'CoreEnterLeaveEvent':
../dix/events.c:4652:12: note: at offset 48 into destination object 'event' of size 32
 4652 |     xEvent event = {
      |            ^

This PR suppresses this warning, by tracking the level of the event (ie., core event, XI or XI2) and ensuring that fix-up is performed only on XI2 events.

Signed-off-by: alex14fr <alex14fr@gmail.com>
This commit is contained in:
Alexandre Janon 2025-08-19 15:36:38 +02:00 committed by Enrico Weigelt
commit 16ee02ab67
4 changed files with 51 additions and 51 deletions

View file

@ -1098,7 +1098,7 @@ DeliverOneTouchEvent(ClientPtr client, DeviceIntPtr dev, TouchPointInfoPtr ti,
FatalError("[Xi] %s: XI2 conversion failed in %s"
" (%d)\n", dev->name, __func__, err);
FixUpEventFromWindow(&ti->sprite, xi2, win, child, FALSE);
FixUpEventFromWindow(&ti->sprite, xi2, win, child, FALSE, XI2);
filter = GetEventFilter(dev, xi2);
if (XaceHookReceiveAccess(client, win, xi2, 1) != Success)
return FALSE;
@ -2237,7 +2237,7 @@ DeliverOneGestureEvent(ClientPtr client, DeviceIntPtr dev, GestureInfoPtr gi,
FatalError("[Xi] %s: XI2 conversion failed in %s"
" (%d)\n", dev->name, __func__, err);
FixUpEventFromWindow(&gi->sprite, xi2, win, child, FALSE);
FixUpEventFromWindow(&gi->sprite, xi2, win, child, FALSE, XI2);
filter = GetEventFilter(dev, xi2);
if (XaceHookReceiveAccess(client, win, xi2, 1) != Success)
return FALSE;

View file

@ -805,7 +805,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
}
FixUpEventFromWindow(dev->spriteInfo->sprite, (xEvent *) xi2event, pWin,
None, FALSE);
None, FALSE, XI2);
DeliverEventsToWindow(dev, pWin, (xEvent *) xi2event, 1,
GetEventFilter(dev, (xEvent *) xi2event), NullGrab);

View file

@ -2686,7 +2686,7 @@ FixUpXI2SwipeEventFromWindow(SpritePtr pSprite, xXIGestureSwipeEvent *event,
*/
void
FixUpEventFromWindow(SpritePtr pSprite,
xEvent *xE, WindowPtr pWin, Window child, Bool calcChild)
xEvent *xE, WindowPtr pWin, Window child, Bool calcChild, enum InputLevel XILevel)
{
int evtype;
@ -2694,38 +2694,40 @@ FixUpEventFromWindow(SpritePtr pSprite,
child = FindChildForEvent(pSprite, pWin);
if ((evtype = xi2_get_type(xE))) {
switch (evtype) {
case XI_RawKeyPress:
case XI_RawKeyRelease:
case XI_RawButtonPress:
case XI_RawButtonRelease:
case XI_RawMotion:
case XI_RawTouchBegin:
case XI_RawTouchUpdate:
case XI_RawTouchEnd:
case XI_DeviceChanged:
case XI_HierarchyChanged:
case XI_PropertyEvent:
case XI_BarrierHit:
case XI_BarrierLeave:
return;
case XI_GesturePinchBegin:
case XI_GesturePinchUpdate:
case XI_GesturePinchEnd:
FixUpXI2PinchEventFromWindow(pSprite,
(xXIGesturePinchEvent*) xE, pWin, child);
break;
case XI_GestureSwipeBegin:
case XI_GestureSwipeUpdate:
case XI_GestureSwipeEnd:
FixUpXI2SwipeEventFromWindow(pSprite,
(xXIGestureSwipeEvent*) xE, pWin, child);
break;
default:
FixUpXI2DeviceEventFromWindow(pSprite, evtype,
(xXIDeviceEvent*) xE, pWin, child);
break;
}
if(XILevel >= XI) {
switch (evtype) {
case XI_RawKeyPress:
case XI_RawKeyRelease:
case XI_RawButtonPress:
case XI_RawButtonRelease:
case XI_RawMotion:
case XI_RawTouchBegin:
case XI_RawTouchUpdate:
case XI_RawTouchEnd:
case XI_DeviceChanged:
case XI_HierarchyChanged:
case XI_PropertyEvent:
case XI_BarrierHit:
case XI_BarrierLeave:
return;
case XI_GesturePinchBegin:
case XI_GesturePinchUpdate:
case XI_GesturePinchEnd:
FixUpXI2PinchEventFromWindow(pSprite,
(xXIGesturePinchEvent*) xE, pWin, child);
break;
case XI_GestureSwipeBegin:
case XI_GestureSwipeUpdate:
case XI_GestureSwipeEnd:
FixUpXI2SwipeEventFromWindow(pSprite,
(xXIGestureSwipeEvent*) xE, pWin, child);
break;
default:
FixUpXI2DeviceEventFromWindow(pSprite, evtype,
(xXIDeviceEvent*) xE, pWin, child);
break;
}
}
}
else {
XE_KBPTR.root = RootWindow(pSprite)->drawable.id;
@ -2804,7 +2806,7 @@ EventIsDeliverable(DeviceIntPtr dev, int evtype, WindowPtr win)
static int
DeliverEvent(DeviceIntPtr dev, xEvent *xE, int count,
WindowPtr win, Window child, GrabPtr grab)
WindowPtr win, Window child, GrabPtr grab, enum InputLevel XILevel)
{
SpritePtr pSprite = dev->spriteInfo->sprite;
Mask filter;
@ -2812,7 +2814,7 @@ DeliverEvent(DeviceIntPtr dev, xEvent *xE, int count,
if (XaceHookSendAccess(NULL, dev, win, xE, count) == Success) {
filter = GetEventFilter(dev, xE);
FixUpEventFromWindow(pSprite, xE, win, child, FALSE);
FixUpEventFromWindow(pSprite, xE, win, child, FALSE, XILevel);
deliveries = DeliverEventsToWindow(dev, win, xE, count, filter, grab);
}
@ -2845,7 +2847,7 @@ DeliverOneEvent(InternalEvent *event, DeviceIntPtr dev, enum InputLevel level,
}
if (rc == Success) {
deliveries = DeliverEvent(dev, xE, count, win, child, grab);
deliveries = DeliverEvent(dev, xE, count, win, child, grab, level);
free(xE);
}
else
@ -3826,7 +3828,7 @@ ActivatePassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event,
ActivateGrabNoDelivery(device, grab, event, real_event);
if (xE) {
FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE, grab->grabtype);
/* XXX: XACE? */
TryClientEvents(dixClientForGrab(grab), device, xE, count,
@ -4224,7 +4226,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
/* XXX: XACE */
int filter = GetEventFilter(keybd, xi2);
FixUpEventFromWindow(ptr->spriteInfo->sprite, xi2, focus, None, FALSE);
FixUpEventFromWindow(ptr->spriteInfo->sprite, xi2, focus, None, FALSE, XI2);
deliveries = DeliverEventsToWindow(keybd, focus, xi2, 1,
filter, NullGrab);
if (deliveries > 0)
@ -4238,7 +4240,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
rc = EventToXI(event, &xE, &count);
if (rc == Success &&
XaceHookSendAccess(NULL, keybd, focus, xE, count) == Success) {
FixUpEventFromWindow(ptr->spriteInfo->sprite, xE, focus, None, FALSE);
FixUpEventFromWindow(ptr->spriteInfo->sprite, xE, focus, None, FALSE, XI);
deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
GetEventFilter(keybd, xE), NullGrab);
@ -4255,8 +4257,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
if (rc == Success) {
if (XaceHookSendAccess(NULL, keybd, focus, core, count) ==
Success) {
FixUpEventFromWindow(keybd->spriteInfo->sprite, core, focus,
None, FALSE);
FixUpEventFromWindow(keybd->spriteInfo->sprite, core, focus, None, FALSE, CORE);
deliveries =
DeliverEventsToWindow(keybd, focus, core, count,
GetEventFilter(keybd, core),
@ -4299,7 +4300,6 @@ DeliverOneGrabbedEvent(InternalEvent *event, DeviceIntPtr dev,
count = 1;
if (rc == Success) {
int evtype = xi2_get_type(xE);
mask = GetXI2MaskByte(grab->xi2mask, dev, evtype);
filter = GetEventFilter(dev, xE);
}
@ -4325,7 +4325,7 @@ DeliverOneGrabbedEvent(InternalEvent *event, DeviceIntPtr dev,
}
if (rc == Success) {
FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE, level);
if (XaceHookSendAccess(NULL, dev, grab->window, xE, count) ||
XaceHookReceiveAccess(dixClientForGrab(grab), grab->window, xE, count))
deliveries = 1; /* don't send, but pretend we did */
@ -4664,7 +4664,7 @@ CoreEnterLeaveEvent(DeviceIntPtr mouse,
{
xEvent event = {
.u.u.type = type,
.u.u.detail = detail
.u.u.detail = detail,
};
WindowPtr focus;
DeviceIntPtr keybd;
@ -4689,7 +4689,7 @@ CoreEnterLeaveEvent(DeviceIntPtr mouse,
event.u.enterLeave.rootX = mouse->spriteInfo->sprite->hot.x;
event.u.enterLeave.rootY = mouse->spriteInfo->sprite->hot.y;
/* Counts on the same initial structure of crossing & button events! */
FixUpEventFromWindow(mouse->spriteInfo->sprite, &event, pWin, None, FALSE);
FixUpEventFromWindow(mouse->spriteInfo->sprite, &event, pWin, None, FALSE, CORE);
/* Enter/Leave events always set child */
event.u.enterLeave.child = child;
event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
@ -4791,8 +4791,7 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
((pWin == focus) || (focus == PointerRootWin) || WindowIsParent(focus, pWin)))
event->focus = TRUE;
FixUpEventFromWindow(mouse->spriteInfo->sprite, (xEvent *) event, pWin,
None, FALSE);
FixUpEventFromWindow(mouse->spriteInfo->sprite, (xEvent *) event, pWin, None, FALSE, XI);
filter = GetEventFilter(mouse, (xEvent *) event);

View file

@ -289,7 +289,8 @@ void FixUpEventFromWindow(SpritePtr pSprite,
xEvent *xE,
WindowPtr pWin,
Window child,
Bool calcChild);
Bool calcChild,
enum InputLevel XILevel);
Bool PointInBorderSize(WindowPtr pWin, int x, int y);
WindowPtr XYToWindow(SpritePtr pSprite, int x, int y);
int EventIsDeliverable(DeviceIntPtr dev, int evtype, WindowPtr win);