Cap slot values to the announced maximum

A malicious device may announce N slots but then send a slot index >= N. The
slot state is almost always allocated (definitely the case in libevdev and
true for most callers), so providing a slot number higher than the announced
maximum is likely to lead to invalid dereferences. Don't allow that.
Likewise, don't allow negative slot numbers.

Note that the kernel filters these events anyway, the only way to trigger this
is to change the device fd to something outside the kernel's control.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Move some functions/macros between libevdev-int.h and libevdev-util.h

This allows libevdev-util.h to be used by tests, it no longer relies on
libevdev internal structs.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Don't sync the MT state for fake MT devices

Devices with ABS_MT_SLOT-1 are fake MT devices, they merely overlap the
axis range but don't actually provide slots. The EVIOCGABS ioctl won't work to
retrieve the current value - the kernel does not store values for those axes
and the return value is always 0.

Thus, simply ignore those axes for fake MT devices and instead rely on the
next event to update the caller with the correct state for each axis.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Send an extra ABS_MT_SLOT event to sync the client up with the current slot

If multiple slots have changed during the sync handling, the client must be
re-set to the current slot before continuing with normal events.

Signed-off-by: Benjamin Tissoires <btissoir@redhat.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
If the tracking ID changes during SYN_DROPPED, terminate the touch first

Most clients can't deal with tracking ID changes unless a -1 is sent first. So
if we notice that the tracking ID has changed during the sync process, send a
set of ABS_MT_TRACKING_ID -1 events for each of those, then send the rest of
the events.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Add a documentation note to update the slot after syncing

Clients may not care about the events generated during SYN_DROPPED, but the
current slot must be updated to avoid a client being out-of-date.
Same with tracking IDs, if they changed, the caller will likely have to update
some internal states.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
test: fix distcheck

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
libevdev 1.1RC1

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
configure: add link to our wiki page

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
doc: Add documentation on how SYN_DROPPED is handled

This is getting a bit complex, so add some high-level documentation that we at
least know what we're trying to do.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
doc: include linux/input.h verbatim in the documentation

This makes it easier to look up what specific version libevdev was compiled
against.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
doc: move the section for the internal test suite down

"Related Pages" in doxygen are ordered in the order they appear in the source
file. The internal test suite is least likely to be of interest to the
reader, so move it to the bottom.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
add a linebreak for correct rendering of the documentation

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Sanitize events when we're skipping sync as well

If a client doesn't sync expliciltly, make sure we sanitize the events when we
update the internal library state.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Shut up compiler warning

Triggered with -O

../libevdev/libevdev.c: In function ‘libevdev_has_event_code’:
../libevdev/libevdev-util.h:58:20: warning: ‘mask’ may be used uninitialized
in this function [-Wmaybe-uninitialized]

Optimisation clearly shuffles things around here: in the code, if no max is
found, we return -1 and bail out before we access mask.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
Shut up another warning

Triggered with -O3

../libevdev/libevdev.c: In function ‘libevdev_get_event_value’:
../libevdev/libevdev.c:1112:6: warning: ‘value’ may be used uninitialized in
this function [-Wmaybe-uninitialized]

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
test: shut up compiler warning

test-libevdev-events.c: In function ‘test_double_syn_dropped_event’:
test-libevdev-events.c:187:2: warning: ignoring return value of ‘read’,
declared with attribute warn_unused_result [-Wunused-result]

This read was there to drain events even when there shouldn't be any on the
pipe anyway. So let's add an assert.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
uinput: check for asprintf failure

This doesn't really do much here, but strictly speaking: if asprintf returns
-1, devnode is undefined. So reset it to NULL to avoid weird pointers. And
also free the rest of the names if we ever have more than one device - which
also shouldn't happen.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>