Bug 38313 - xorg-server crashes on keyboard BTN events
Summary: xorg-server crashes on keyboard BTN events
Alias: None
Product: xorg
Classification: Unclassified
Component: Server/Input/Core (show other bugs)
Version: 7.6 (2010.12)
Hardware: x86-64 (AMD64) Linux (All)
: medium major
Assignee: Peter Hutterer
QA Contact: Xorg Project Team
Whiteboard: 2011BRB_Reviewed
Keywords: regression
Depends on:
Blocks: xserver-1.12
  Show dependency treegraph
Reported: 2011-06-14 12:34 UTC by David Herrmann
Modified: 2012-02-27 19:46 UTC (History)
3 users (show)

See Also:
i915 platform:
i915 features:

Xorg.0.log (27.44 KB, text/plain)
2011-06-14 12:34 UTC, David Herrmann
no flags Details
Xorg.0.log crash with evdev keyboard and mouse (25.60 KB, text/x-log)
2011-07-15 06:32 UTC, Chris Humbert
no flags Details
0001-dix-don-t-XWarpPointer-through-the-last-slave-anymor.patch (1.16 KB, patch)
2011-07-28 23:41 UTC, Peter Hutterer
no flags Details | Splinter Review
0001-input-store-the-highest-valuator-in-DeviceEvents-and.patch (11.84 KB, patch)
2011-07-31 18:42 UTC, Peter Hutterer
no flags Details | Splinter Review
0002-mi-only-dequeue-the-current-screen-if-we-have-valuat.patch (1.84 KB, patch)
2011-07-31 18:44 UTC, Peter Hutterer
no flags Details | Splinter Review
Evemu device (700 bytes, text/plain)
2012-02-21 12:11 UTC, Matthew Monaco
no flags Details
Evemu record (132 bytes, text/plain)
2012-02-21 12:12 UTC, Matthew Monaco
no flags Details
cwiid config file (1.03 KB, text/plain)
2012-02-21 12:13 UTC, Matthew Monaco
no flags Details

Description David Herrmann 2011-06-14 12:34:20 UTC
Created attachment 47968 [details]

I have a input device which reports BTN_1 and BTN_2 events (because it has a button labeled "1" and "2") via /dev/input/eventX.
If I now press BTN_1 followed by alt+tab to switch applications, then the x-server crashes with:

[344937.430] 0: X (xorg_backtrace+0x26) [0x49f556]
[344937.431] 1: X (0x400000+0x60cf9) [0x460cf9]
[344937.431] 2: /lib/libpthread.so.0 (0x7fe800161000+0xf750) [0x7fe800170750]
[344937.431] 3: X (GetPointerEvents+0xc55) [0x442bf5]
[344937.431] 4: X (miPointerWarpCursor+0x130) [0x459030]
[344937.431] 5: X (0x400000+0x122111) [0x522111]
[344937.431] 6: X (0x400000+0x59582) [0x459582]
[344937.431] 7: X (0x400000+0x163a23) [0x563a23]
[344937.431] 8: X (ProcWarpPointer+0x422) [0x43ac92]
[344937.431] 9: X (0x400000+0x2e8d9) [0x42e8d9]
[344937.432] 10: X (0x400000+0x22b7e) [0x422b7e]
[344937.432] 11: /lib/libc.so.6 (__libc_start_main+0xed) [0x7fe7ff0e1f6d]
[344937.432] 12: X (0x400000+0x22e6d) [0x422e6d]
[344937.432] Segmentation fault at address 0x20
Fatal server error:
[344937.432] Caught signal 11 (Segmentation fault). Server aborting
Please consult the The X.Org Foundation support 
         at http://wiki.x.org
 for help. 
[344937.432] Please also check the log file at "/var/log/Xorg.1.log" for additional information.

I don't have a binary with debug symbols since my distro doesn't provide one, sadly...
One more thing:
The segfault occurs when switching applications, however, only if no other mouse-event is between the BTN_1 and window-switch. If I move then mouse or press another mouse button between BTN_1 and alt+tab, then the bug doesn't occur.

Comment 1 David Herrmann 2011-06-14 12:42:01 UTC
I have narrowed it down. My device (The Nintendo Wiimote as listed in the xorg-log) has the following xorg-config:

Section "InputClass"
        Identifier "Nintendo Wiiremote Blacklist"
        MatchProduct "Nintendo Wii Remote"
        Option "IgnoreAbsoluteAxes" "true"

If I remove the "IgnoreAbsoluteAxes" line, then the bug does not occur. So I think that some input-handling code tries to read absolute Axes on BTN_1 events although they are disabled.

Comment 2 Chris Humbert 2011-07-15 06:32:39 UTC
Created attachment 49149 [details]
Xorg.0.log crash with evdev keyboard and mouse

I'm encountering the same bug in the standard evdev keyboard and mouse configuration while playing ioquake3. Calling GetPointerEvents with pDev->valuator == NULL causes the crash. In my case, this happens sporadically within 1-30 minutes.

Program received signal SIGSEGV, Segmentation fault.
0x0000000000445c96 in GetPointerEvents (events=<value optimized out>, pDev=0x2993cb0, type=6, buttons=<value optimized out>, flags=16, mask_in=<value optimized out>) at ../../xorg-server-1.10.3/dix/getevents.c:1156
1156 scaled = rescaleValuatorAxis(valuator_mask_get(&mask, 0),
1157                              0.0, &x_frac, NULL,
1158                              pDev->valuator->axes + 0,
1159                              scr->width);

(gdb) backtrace
#0  0x0000000000445c96 in GetPointerEvents (events=<value optimized out>, pDev=0x2993cb0, type=6, buttons=<value optimized out>, flags=16, mask_in=<value optimized out>) at ../../xorg-server-1.10.3/dix/getevents.c:1156
#1  0x000000000045d41b in miPointerMove (pDev=0x2993cb0, pScreen=0x243a980, x=0, y=0) at ../../xorg-server-1.10.3/mi/mipointer.c:576
#2  miPointerWarpCursor (pDev=0x2993cb0, pScreen=0x243a980, x=0, y=0) at ../../xorg-server-1.10.3/mi/mipointer.c:310
#3  0x0000000000525e71 in xf86WarpCursor (pDev=0x2993cb0, pScreen=0x243a980, x=0, y=0) at ../../../../xorg-server-1.10.3/hw/xfree86/common/xf86Cursor.c:473
#4  0x000000000045dd3f in miPointerSetCursorPosition (pDev=0x2993cb0, pScreen=0x0, x=37988736, y=0, generateEvent=1) at ../../xorg-server-1.10.3/mi/mipointer.c:233
#5  0x00000000005679df in AnimCurSetCursorPosition (pDev=0x7fffe0127360, pScreen=0x243a980, x=37988736, y=0, generateEvent=0) at ../../xorg-server-1.10.3/render/animcur.c:261
#6  0x000000000043ab56 in CheckPhysLimits (pDev=0x2993cb0, cursor=<value optimized out>, generateEvents=1, confineToScreen=0, pScreen=0x0) at ../../xorg-server-1.10.3/dix/events.c:744
#7  0x000000000043b16d in NewCurrentScreen (pDev=0x2993cb0, newScreen=<value optimized out>, x=<value optimized out>, y=<value optimized out>) at ../../xorg-server-1.10.3/dix/events.c:3083
#8  0x000000000045b252 in mieqProcessDeviceEvent (dev=0x2993cb0, event=0x2a08690, screen=0x24a5e10) at ../../xorg-server-1.10.3/mi/mieq.c:394
#9  0x000000000045b320 in mieqProcessInputEvents () at ../../xorg-server-1.10.3/mi/mieq.c:481
#10 0x000000000046e9b9 in ProcessInputEvents () at ../../../../xorg-server-1.10.3/hw/xfree86/common/xf86Events.c:165
#11 0x0000000000431ae3 in Dispatch () at ../../xorg-server-1.10.3/dix/dispatch.c:363
#12 0x0000000000425b0a in main (argc=6, argv=0x7fffe0127fe8, envp=<value optimized out>) at ../../xorg-server-1.10.3/dix/main.c:287

(gdb) disas
=> 0x0000000000445c96 <+3062>:	mov    0x20(%rax),%r14

(gdb) i r rax
rax            0x0	0
Comment 3 Chris Humbert 2011-07-15 11:59:09 UTC
--- What's happening:

1. A pointer event moves the pointer outside of its confined area.
2. mieqProcessDeviceEvent starts processing a KeyPress event from a keyboard.
3. NewCurrentScreen determines the pointer is outside of its confined area.
4. miPointerMove warps the pointer back into its confined area, generating a
   MotionNotify event from the keyboard.
6. GetPointerEvents attempts to use the keyboard's NULL DeviceIntPtr->valuator
   to scale, transform, and clip the MotionNotify event.

--- What's the best way to fix this?

1. Check that the pointer is confined only after moving the pointer.
2. Check that the pointer is confined only during pointer events.
3. Only generate move events from pointer devices.
4. Ignore pointer events from non-pointer devices.
Comment 4 Peter Hutterer 2011-07-28 23:41:25 UTC
Created attachment 49702 [details] [review]

David: I believe this is the correct fix for your problem. Chris' problem is slightly different, needs a separate fix.
Comment 5 Peter Hutterer 2011-07-31 18:42:08 UTC
Created attachment 49765 [details] [review]

patch required for the actual fix
Comment 6 Peter Hutterer 2011-07-31 18:44:00 UTC
Created attachment 49766 [details] [review]

Events without valuators cannot change the screen. Check if the event does
actually include valuators before generating one to stop null-pointer dereferences.
Comment 7 Peter Hutterer 2011-09-01 20:34:06 UTC
(In reply to comment #4)
> Created an attachment (id=49702) [details]
> 0001-dix-don-t-XWarpPointer-through-the-last-slave-anymor.patch

this one is in my -next branch, will be upstream soon.

Chris, for your issue see the thread here: http://lists.freedesktop.org/archives/xorg-devel/2011-September/024801.html
Comment 8 Jeremy Huddleston Sequoia 2011-11-03 02:00:06 UTC
This introduces a regression:

Comment 9 Jeremy Huddleston Sequoia 2011-11-03 22:52:09 UTC
This change has been reverted from the 1.11 branch.

This change still exists in master and should be fixed or reverted before 1.12 is released.  Marking as a 1.12 blocker.
Comment 10 Matthew Monaco 2012-02-20 12:49:59 UTC
I'm unclear as to which patches are supposed to fix the issue. Is it all 3? Or just the latter of the 0001 and then 0002?

I'm currently running xorg and evdev The server picks up the main device from the hid-wiimote module which it considers a keyboard, but it has a mouse button. If I press it, the server crashes.

If instead I ignore those devices and use a userspace translator, the x server gets a device through uinput. If the uninput device has an axis and mouse button, no crash. If I disable the axis I get a crash when I press the mouse button. (the log still shows it is a keyboard and as a mouse even when the axis is disabled).
Comment 11 Peter Hutterer 2012-02-20 20:37:29 UTC
Please get evemu and record the device plus the event that makes the server crash, then attach both files here. Thanks.
Comment 12 Matthew Monaco 2012-02-21 12:11:02 UTC
Created attachment 57414 [details]
Evemu device

This is the uinput device which causes Xorg to crash.
Comment 13 Matthew Monaco 2012-02-21 12:12:42 UTC
Created attachment 57415 [details]
Evemu record

This is a record of the event leading to the crash. The only data there should be me pressing the wiimote button I have mapped to BTN_LEFT.
Comment 14 Matthew Monaco 2012-02-21 12:13:43 UTC
Created attachment 57416 [details]
cwiid config file

Just in case, these are the button mappings that the uinput device for the wiimote should have. It shouldn't have any other capabilities.
Comment 15 Peter Hutterer 2012-02-21 21:48:44 UTC
Comment 16 Matthew Monaco 2012-02-21 22:24:10 UTC
That did the trick. Thank you Peter.
Comment 17 David Herrmann 2012-02-22 02:10:25 UTC
Yes, that did it. Thanks Peter!
Comment 18 Peter Hutterer 2012-02-22 02:16:04 UTC
Please leave the bug open until the commit is upstream, we can close it once we have a commitid.
Comment 19 Peter Hutterer 2012-02-27 19:46:17 UTC
commit 2416ee4a015068359807a10f433e8c54192c78a9
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Wed Feb 22 15:32:56 2012 +1000

    dix: avoid NULL-pointer dereference on button-only devices (#38313)

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.