Bug 29669 - X Server Crashes when removing an input device
Summary: X Server Crashes when removing an input device
Alias: None
Product: xorg
Classification: Unclassified
Component: Server/Input/Core (show other bugs)
Version: unspecified
Hardware: x86 (IA32) Linux (All)
: medium normal
Assignee: Peter Hutterer
QA Contact: Xorg Project Team
Depends on:
Blocks: xserver-1.9
  Show dependency treegraph
Reported: 2010-08-19 03:03 UTC by xorg
Modified: 2010-09-17 16:37 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Description xorg 2010-08-19 03:03:37 UTC

    The X Server crashes when an input device is removed while the master input device has no button.

Steps to Reproduce:

    You need to have an input device with no button (in my case, it is a lis3lv02d accelerometer)
    1) Connect a USB mouse.
    2) Start X server.
    3) Remove the USB mouse.

Actual Results:

    X Server crashes:

    0: /usr/bin/X (xorg_backtrace+0x3c) [0x80d504c]
    1: /usr/bin/X (0x8047000+0x5ae56) [0x80a1e56]
    2: (vdso) (__kernel_rt_sigreturn+0x0) [0xb787840c]
    3: /usr/bin/X (0x8047000+0x43245) [0x808a245]
    4: /usr/bin/X (DisableDevice+0x22f) [0x808a7af]
    5: /usr/bin/X (RemoveDevice+0x223) [0x808aaa3]
    6: /usr/bin/X (DeleteInputDeviceRequest+0x4e) [0x80b9b8e]
    7: /usr/bin/X (0x8047000+0x116f70) [0x815df70]
    8: /usr/bin/X (0x8047000+0x117039) [0x815e03a]
    9: /usr/bin/X (0x8047000+0x117dd9) [0x815edd9]
    10: /usr/bin/X (WakeupHandler+0x4f) [0x808dd3f]
    11: /usr/bin/X (WaitForSomething+0x1a2) [0x80a1362]
    12: /usr/bin/X (0x8047000+0x299fe) [0x80709fe]
    13: /usr/bin/X (0x8047000+0x1bbaa) [0x8062baa]
    14: /lib/libc.so.6 (__libc_start_main+0xe7) [0x533bb7]
    15: /usr/bin/X (0x8047000+0x1b7a1) [0x80627a1]
    Segmentation fault at address 0x5

    Fatal server error:
    Caught signal 11 (Segmentation fault). Server aborting

Expected Results:

    X Server shall not crashed.

Build Date & Platform:

    X.Org X Server (1.9.0 RC 5)
    Release Date: 2010-07-14
    X Protocol Version 11, Revision 0
    Build Operating System: Linux i686 

Additional Information:

    When removing a USB mouse, a Segmentation fault occurs in RecalculateMasterButtons:

    Program received signal SIGSEGV, Segmentation fault.
    0x08097845 in RecalculateMasterButtons (slave=<value optimized out>) at devices.c:2343
    2343	    if (master->button->numButtons != maxbuttons)
    (gdb) backtrace
    #0  0x08097845 in RecalculateMasterButtons (slave=<value optimized out>) at devices.c:2343
    #1  0x08097daf in DisableDevice (dev=0xa1fb810, sendevent=1 '\001') at devices.c:508
    #2  0x080980a3 in RemoveDevice (dev=0xa1fb810, sendevent=1 '\001') at devices.c:1055
    #3  0x080aeb8e in DeleteInputDeviceRequest (pDev=0xa1fb810) at xf86Xinput.c:952
    #4  0x080bbd50 in remove_device (backend=<value optimized out>, dev=0xa1fb810) at config.c:84
    #5  0x080bbe19 in remove_devices (backend=0x81c57b1 "udev", config_info=0xa1fe068 "udev:/sys/devices/pci0000:00/0000:00:02.3/usb1/1-1/1-1.1/1-1.1:1.1/input/input13/event9") at config.c:96
    #6  0x080ceb79 in device_removed (data=0x0, err=1, read_mask=0x8226680) at udev.c:235
    #7  wakeup_handler (data=0x0, err=1, read_mask=0x8226680) at udev.c:259
    #8  0x0806eacf in WakeupHandler (result=1, pReadmask=0x8226680) at dixutils.c:419
    #9  0x080aa932 in WaitForSomething (pClientsReady=0xa202bb8) at WaitFor.c:232
    #10 0x08069c5e in Dispatch () at dispatch.c:368
    #11 0x08062baa in main (argc=4, argv=0xbfa1b0c4, envp=0xbfa1b0d8) at main.c:291

    a Segmentation fault occurs since master->button is NULL.

    During execution, an input device with no button has become the master input device.
    On ET_DeviceChanged event, ChangeMasterDeviceClasses calls DeepCopyPointerClasses with to->button equals to NULL
    and from->button different from NULL (was allocated by InitPointerDeviceStruct).
    In this case, from->button is saved in to->unused_classes and to->button (new master input device) is set to NULL.

        } else if (to->button && !from->button)
            ClassesPtr classes;
            classes = to->unused_classes;
            classes->button = to->button;
            to->button      = NULL;

    When an input device is removed, RecalculateMasterButtons is called (see previous backtrace).
    In the latter processing, there is an access to master input device button field (which has been previously set to NULL).

        if (master->button->numButtons != maxbuttons)

    There is no check on master->button that leads to a Segmentation fault.
Comment 1 Jesse Adkins 2010-09-17 16:37:59 UTC
Fixed on Aug 23 2010 by git commit ff055506f0cbb852bed17acb9f9bbf1d715a854e.

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.