99 lines
3.9 KiB
Diff
99 lines
3.9 KiB
Diff
From 6ef5c05728f8b18170fbc8415d7502495a08670b Mon Sep 17 00:00:00 2001
|
|
From: Povilas Kanapickas <povilas@radix.lt>
|
|
Date: Sun, 23 Jan 2022 22:18:52 +0200
|
|
Subject: [PATCH] dix: Correctly save replayed event into GrabInfoRec
|
|
|
|
When processing events we operate on InternalEvent pointers. They may
|
|
actually refer to a an instance of DeviceEvent, GestureEvent or any
|
|
other event that comprises the InternalEvent union. This works well in
|
|
practice because we always look into event type before doing anything,
|
|
except in the case of copying the event.
|
|
|
|
*dst_event = *src_event would copy whole InternalEvent event and would
|
|
cause out of bounds read in case the pointed to event was not
|
|
InternalEvent but e.g. DeviceEvent.
|
|
|
|
This regression has been introduced in
|
|
23a8b62d34344575f9df9d057fb74bfefa94a77b.
|
|
|
|
Fixes https://gitlab.freedesktop.org/xorg/xserver/-/issues/1261
|
|
|
|
Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
|
|
---
|
|
Xi/exevents.c | 2 +-
|
|
dix/events.c | 18 ++++++++++++++++--
|
|
include/input.h | 1 +
|
|
3 files changed, 18 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/Xi/exevents.c b/Xi/exevents.c
|
|
index 94b9983bd..217baa956 100644
|
|
--- a/Xi/exevents.c
|
|
+++ b/Xi/exevents.c
|
|
@@ -1524,7 +1524,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
|
|
g = AllocGrab(devgrab);
|
|
BUG_WARN(!g);
|
|
|
|
- *dev->deviceGrab.sync.event = *ev;
|
|
+ CopyPartialInternalEvent(dev->deviceGrab.sync.event, ev);
|
|
|
|
/* The listener array has a sequence of grabs and then one event
|
|
* selection. Implicit grab activation occurs through delivering an
|
|
diff --git a/dix/events.c b/dix/events.c
|
|
index 341c746d4..28d7d177c 100644
|
|
--- a/dix/events.c
|
|
+++ b/dix/events.c
|
|
@@ -467,6 +467,20 @@ WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent *ev)
|
|
return xi2mask_isset(inputMasks->xi2mask, dev, evtype);
|
|
}
|
|
|
|
+/**
|
|
+ * When processing events we operate on InternalEvent pointers. They may actually refer to a
|
|
+ * an instance of DeviceEvent, GestureEvent or any other event that comprises the InternalEvent
|
|
+ * union. This works well in practice because we always look into event type before doing anything,
|
|
+ * except in the case of copying the event. Any copying of InternalEvent should use this function
|
|
+ * instead of doing *dst_event = *src_event whenever it's not clear whether source event actually
|
|
+ * points to full InternalEvent instance.
|
|
+ */
|
|
+void
|
|
+CopyPartialInternalEvent(InternalEvent* dst_event, const InternalEvent* src_event)
|
|
+{
|
|
+ memcpy(dst_event, src_event, src_event->any.length);
|
|
+}
|
|
+
|
|
Mask
|
|
GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients * other)
|
|
{
|
|
@@ -3873,7 +3887,7 @@ void ActivateGrabNoDelivery(DeviceIntPtr dev, GrabPtr grab,
|
|
|
|
if (grabinfo->sync.state == FROZEN_NO_EVENT)
|
|
grabinfo->sync.state = FROZEN_WITH_EVENT;
|
|
- *grabinfo->sync.event = *real_event;
|
|
+ CopyPartialInternalEvent(grabinfo->sync.event, real_event);
|
|
}
|
|
|
|
static BOOL
|
|
@@ -4455,7 +4469,7 @@ FreezeThisEventIfNeededForSyncGrab(DeviceIntPtr thisDev, InternalEvent *event)
|
|
case FREEZE_NEXT_EVENT:
|
|
grabinfo->sync.state = FROZEN_WITH_EVENT;
|
|
FreezeThaw(thisDev, TRUE);
|
|
- *grabinfo->sync.event = *event;
|
|
+ CopyPartialInternalEvent(grabinfo->sync.event, event);
|
|
break;
|
|
}
|
|
}
|
|
diff --git a/include/input.h b/include/input.h
|
|
index b1aef3663..cdb5d5a90 100644
|
|
--- a/include/input.h
|
|
+++ b/include/input.h
|
|
@@ -676,6 +676,7 @@ extern void GestureEmitGestureEndToOwner(DeviceIntPtr dev, GestureInfoPtr gi);
|
|
extern void ProcessGestureEvent(InternalEvent *ev, DeviceIntPtr dev);
|
|
|
|
/* misc event helpers */
|
|
+extern void CopyPartialInternalEvent(InternalEvent* dst_event, const InternalEvent* src_event);
|
|
extern Mask GetEventMask(DeviceIntPtr dev, xEvent *ev, InputClientsPtr clients);
|
|
extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);
|
|
extern Bool WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent *ev);
|
|
--
|
|
GitLab
|
|
|