Bug 29669

Summary: X Server Crashes when removing an input device
Product: xorg Reporter: xorg
Component: Server/Input/CoreAssignee: Peter Hutterer <peter.hutterer>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Bug Depends on:    
Bug Blocks: 27592    

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

    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:

    Backtrace:
    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.8.99.905 (1.9.0 RC 5)
    Release Date: 2010-07-14
    X Protocol Version 11, Revision 0
    Build Operating System: Linux 2.6.31.12-0.2-desktop 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) 
    (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.