Differential D35661 Diff 108629 x11-servers/xorg-server/files/0003-dix_Correctly_save_replayed_event_into_GrabInfoRec.patch
Changeset View
Changeset View
Standalone View
Standalone View
x11-servers/xorg-server/files/0003-dix_Correctly_save_replayed_event_into_GrabInfoRec.patch
- This file was added.
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 | |||||