• David Herrmann's avatar
    Input: evdev - flush queues during EVIOCGKEY-like ioctls · 48318028
    David Herrmann authored
    If userspace requests current KEY-state, they very likely assume that no
    such events are pending in the output queue of the evdev device.
    Otherwise, they will parse events which they already handled via
    EVIOCGKEY(). For XKB applications this can cause irreversible keyboard
    states if a modifier is locked multiple times because a CTRL-DOWN event is
    handled once via EVIOCGKEY() and once from the queue via read(), even
    though it should handle it only once.
    
    Therefore, lets do the only logical thing and flush the evdev queue
    atomically during this ioctl. We only flush events that are affected by
    the given ioctl.
    
    This only affects boolean events like KEY, SND, SW and LED. ABS, REL and
    others are not affected as duplicate events can be handled gracefully by
    user-space.
    
    Note: This actually breaks semantics of the evdev ABI. However,
    investigations showed that userspace already expects the new semantics and
    we end up fixing at least all XKB applications.
    All applications that are aware of this race-condition mirror the KEY
    state for each open-file and detect/drop duplicate events. Hence, they do
    not care whether duplicates are posted or not and work fine with this fix.
    
    Also note that we need proper locking to guarantee atomicity and avoid
    dead-locks. event_lock must be locked before queue_lock (see input-core).
    However, we can safely release event_lock while flushing the queue. This
    allows the input-core to proceed with pending events and only stop if it
    needs our queue_lock to post new events.
    This should guarantee that we don't block event-dispatching for too long
    while flushing a single event queue.
    Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
    Acked-by: default avatarPeter Hutterer <peter.hutterer@who-t.net>
    Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
    48318028
evdev.c 27.2 KB