Blame SOURCES/0001-mi-don-t-process-events-from-disabled-devices-77884.patch

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