|
|
0b0bd3 |
From e0e84775030cce77b37bb87739bebfd6635ea303 Mon Sep 17 00:00:00 2001
|
|
|
0b0bd3 |
From: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
0b0bd3 |
Date: Wed, 21 May 2014 10:07:31 +1000
|
|
|
0b0bd3 |
Subject: [PATCH 1/3] mi: don't process events from disabled devices (#77884)
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
Once a device is disabled, it doesn't have a sprite pointer anymore. If an
|
|
|
0b0bd3 |
event is still in the queue and processed after DisableDevice finished, a
|
|
|
0b0bd3 |
dereference causes a crash. Example backtrace (crash forced by injecting an
|
|
|
0b0bd3 |
event at the right time):
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
(EE) 0: /opt/xorg/bin/Xorg (OsSigHandler+0x3c) [0x48d334]
|
|
|
0b0bd3 |
(EE) 1: /lib64/libpthread.so.0 (__restore_rt+0x0) [0x37fcc0f74f]
|
|
|
0b0bd3 |
(EE) 2: /opt/xorg/bin/Xorg (mieqMoveToNewScreen+0x38) [0x609240]
|
|
|
0b0bd3 |
(EE) 3: /opt/xorg/bin/Xorg (mieqProcessDeviceEvent+0xd4) [0x609389]
|
|
|
0b0bd3 |
(EE) 4: /opt/xorg/bin/Xorg (mieqProcessInputEvents+0x206) [0x609720]
|
|
|
0b0bd3 |
(EE) 5: /opt/xorg/bin/Xorg (ProcessInputEvents+0xd) [0x4aeb58]
|
|
|
0b0bd3 |
(EE) 6: /opt/xorg/bin/Xorg (xf86VTSwitch+0x1a6) [0x4af457]
|
|
|
0b0bd3 |
(EE) 7: /opt/xorg/bin/Xorg (xf86Wakeup+0x2bf) [0x4af0a7]
|
|
|
0b0bd3 |
(EE) 8: /opt/xorg/bin/Xorg (WakeupHandler+0x83) [0x4445cb]
|
|
|
0b0bd3 |
(EE) 9: /opt/xorg/bin/Xorg (WaitForSomething+0x3fe) [0x491bf6]
|
|
|
0b0bd3 |
(EE) 10: /opt/xorg/bin/Xorg (Dispatch+0x97) [0x435748]
|
|
|
0b0bd3 |
(EE) 11: /opt/xorg/bin/Xorg (dix_main+0x61d) [0x4438a9]
|
|
|
0b0bd3 |
(EE) 12: /opt/xorg/bin/Xorg (main+0x28) [0x49ba28]
|
|
|
0b0bd3 |
(EE) 13: /lib64/libc.so.6 (__libc_start_main+0xf5) [0x37fc821d65]
|
|
|
0b0bd3 |
(EE) 14: /opt/xorg/bin/Xorg (_start+0x29) [0x425e69]
|
|
|
0b0bd3 |
(EE) 15: ? (?+0x29) [0x29]
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
xf86VTSwitch() calls ProcessInputEvents() before disabling a device, and
|
|
|
0b0bd3 |
DisableDevice() calls mieqProcessInputEvents() again when flushing touches and
|
|
|
0b0bd3 |
button events. Between that and disabling the device (which causes new events
|
|
|
0b0bd3 |
to be refused) there is a window where events may be triggered and enqueued.
|
|
|
0b0bd3 |
On the next call to PIE that event is processed on a now defunct device,
|
|
|
0b0bd3 |
causing the crash.
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
The simplest fix to this is to discard events from disabled devices. We flush
|
|
|
0b0bd3 |
the queue often enough before disabling that when we get here, we really don't
|
|
|
0b0bd3 |
care about the events from this device.
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
X.Org Bug 77884 <http://bugs.freedesktop.org/show_bug.cgi?id=77884>
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
|
|
|
0b0bd3 |
Reported-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
|
|
|
0b0bd3 |
Tested-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
|
|
|
0b0bd3 |
Reviewed-by: Keith Packard <keithp@keithp.com>
|
|
|
0b0bd3 |
Signed-off-by: Keith Packard <keithp@keithp.com>
|
|
|
0b0bd3 |
(cherry picked from commit 9fb08310b51b46736f3ca8dbc04efdf502420403)
|
|
|
0b0bd3 |
---
|
|
|
0b0bd3 |
mi/mieq.c | 4 ++++
|
|
|
0b0bd3 |
test/input.c | 14 +++++++++++++-
|
|
|
0b0bd3 |
2 files changed, 17 insertions(+), 1 deletion(-)
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
diff --git a/mi/mieq.c b/mi/mieq.c
|
|
|
0b0bd3 |
index 4c07480..188a0b0 100644
|
|
|
0b0bd3 |
--- a/mi/mieq.c
|
|
|
0b0bd3 |
+++ b/mi/mieq.c
|
|
|
0b0bd3 |
@@ -515,6 +515,10 @@ mieqProcessDeviceEvent(DeviceIntPtr dev, InternalEvent *event, ScreenPtr screen)
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
verify_internal_event(event);
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
+ /* refuse events from disabled devices */
|
|
|
0b0bd3 |
+ if (!dev->enabled)
|
|
|
0b0bd3 |
+ return 0;
|
|
|
0b0bd3 |
+
|
|
|
0b0bd3 |
/* Custom event handler */
|
|
|
0b0bd3 |
handler = miEventQueue.handlers[event->any.type];
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
diff --git a/test/input.c b/test/input.c
|
|
|
0b0bd3 |
index df20f82..4603c60 100644
|
|
|
0b0bd3 |
--- a/test/input.c
|
|
|
0b0bd3 |
+++ b/test/input.c
|
|
|
0b0bd3 |
@@ -1708,6 +1708,18 @@ mieq_test_event_handler(int screenNum, InternalEvent *ie, DeviceIntPtr dev)
|
|
|
0b0bd3 |
static void
|
|
|
0b0bd3 |
_mieq_test_generate_events(uint32_t start, uint32_t count)
|
|
|
0b0bd3 |
{
|
|
|
0b0bd3 |
+ static DeviceIntRec dev;
|
|
|
0b0bd3 |
+ static SpriteInfoRec spriteInfo;
|
|
|
0b0bd3 |
+ static SpriteRec sprite;
|
|
|
0b0bd3 |
+
|
|
|
0b0bd3 |
+ memset(&dev, 0, sizeof(dev));
|
|
|
0b0bd3 |
+ memset(&spriteInfo, 0, sizeof(spriteInfo));
|
|
|
0b0bd3 |
+ memset(&sprite, 0, sizeof(sprite));
|
|
|
0b0bd3 |
+ dev.spriteInfo = &spriteInfo;
|
|
|
0b0bd3 |
+ spriteInfo.sprite = &sprite;
|
|
|
0b0bd3 |
+
|
|
|
0b0bd3 |
+ dev.enabled = 1;
|
|
|
0b0bd3 |
+
|
|
|
0b0bd3 |
count += start;
|
|
|
0b0bd3 |
while (start < count) {
|
|
|
0b0bd3 |
RawDeviceEvent e = { 0 };
|
|
|
0b0bd3 |
@@ -1717,7 +1729,7 @@ _mieq_test_generate_events(uint32_t start, uint32_t count)
|
|
|
0b0bd3 |
e.time = GetTimeInMillis();
|
|
|
0b0bd3 |
e.flags = start;
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
- mieqEnqueue(NULL, (InternalEvent *) &e);
|
|
|
0b0bd3 |
+ mieqEnqueue(&dev, (InternalEvent *) &e);
|
|
|
0b0bd3 |
|
|
|
0b0bd3 |
start++;
|
|
|
0b0bd3 |
}
|
|
|
0b0bd3 |
--
|
|
|
0b0bd3 |
1.9.3
|
|
|
0b0bd3 |
|