A few not-really-an-issue fixes found by Claude:
1. ctx->buttons_down[number]: the 'number' value comes from
libinput_event_tablet_pad_get_button_number() and is written into
a fixed-size array of 32 elements without bounds checking. A crafted
or malicious device reporting button numbers >= 32 causes a stack
buffer overflow.
2. ctx->ring[number], ctx->strip[number], ctx->dial[number]: these are
fixed-size arrays of 2 elements each. Ring/strip/dial numbers from
libinput events are used as indices without bounds checking. Values
>= 2 cause out-of-bounds writes.
3. assert()-based error handling for open() and libevdev_new_from_fd():
assert() is compiled to a no-op in release builds (NDEBUG). This
means that in release builds, a failed open() returns fd=-1, and
libevdev_new_from_fd() is called with an invalid fd. The result is
undefined behavior.
4. Variable-length array (VLA) 'empty[termwidth]' in print_bar():
termwidth comes from an ioctl(TIOCGWINSZ) call and could be very
large, causing a stack overflow. Replace with a fixed-size buffer.
None of these really matter for a niche debugging tool.
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1467>
The fd opened for the evdev device is never stored in ctx->fds[1].fd
so we never poll for it. Real impact was limited since we do poll for
the libinput fd and we process libevdev events whenever any of the fds
triggers.
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
fread(buf, sizeof(buf), 1, dmi) reads one block of 2048 bytes,
returning the number of complete blocks (0 or 1). Since DMI modalias
files are always shorter than 2048 bytes, fread returns 0 even when
data was successfully read into buf. The 'if (n > 0)' check then
always fails and the DMI string stays as "unknown".
Swap the size and nmemb arguments so fread returns the number of
bytes read instead.
Fixes: 0ecd08c134 ("tools: use __attribute__(cleanup)")
Co-Authored-by: Claude Code <noreply@anthropic.com>
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1444>
If the tool has a name let's provide that to the caller. We have it
easily accessible so let's export it to make everyone's life easier. The
name is provided by libwacom, there is no need for us
to even copy that value since we don't need it ourselves.
Note that at this point effectively only (some) Wacom devices have
meaningful names. Virtually all non-wacom devices will use a generic
tool and even the built-in Wacoms will largely just say "AES Pen".
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1399>
"libinput_plugins_flags" is bound to be annoying to approximately
everyone who'll ever have to use them so let's rename this while we
still can. Renamed to libinput_plugin_system_flags to leave the
namespace open for a possible future libinput_plugin_flags that works
on individual plugins.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1337>
Python 3.14 has changed from fork to forkserver[1] which causes
libinput replay to fail with the following error when starting the
subprocesses:
ValueError: ctypes objects containing pointers cannot be pickled
This is caused by the libevdev device being passed to the sub process.
A more proper fix may be to only initialize the device in the subprocess
and then signal the process to start replaying. But meanwhile, switching
back to fork will do.
[1] https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methodsCloses#1204
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1330>
This patch adds a new API for enabling public "plugins" in libinput, in
addition to the exisitng internal ones. The API is currently limited to
specifying which paths should be loaded and whether to load them.
Public plugins are static, they are loaded before the context is initialized
and do not update after that.
If plugins are to be loaded, libinput will then run through those paths,
look up files and pass them to (future) plugins to load the actual
files.
Our debugging tools have an --enable-plugins and
--disable-plugins option that load from the default data paths
(/etc/libinput/plugins and /usr/lib{64}/libinput/plugins) and from
the $builddir/plugins directory.
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1192>
config.set10 is much more convenient and nicer to read but can provide
false positive if the value is 0 and #ifdef is used instead of #if. So
let's switch everything to use #ifdef instead, that way we cannot get
false positives if the value is unset.
Closes#1162
Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1277>