Thread (9 messages) 9 messages, 3 authors, 2021-03-20

[BUG]an input device can not support more than 568 keys due to uevent buffer too small

From: Zhai Zhaoxuan <hidden>
Date: 2021-03-13 06:33:57

Hi Dmitry and Greg,

I recently started making a keyboard utility. It basically helps the
user press some keys based on a user script.
So I tried to use the "uinput" driver to help me send keys to the kernel.

Due to any key and combination can be requested by the user script, I
tried to enable all KEYBIT on the uinput device. But it fails.
And more accurate, using a binary search, it seems that I am unable to
enable more than 568 keys.
The KEY_MAX (defined in linux/input-event-codes.h) is 0x2ff. So it
should be ok to enable 767 keys. The uinput device should not fail
with only 568 keys.

I read system logs. The log shows that the new input device fails due
to systemd-udevd trying to read
`/sys/devices/virtual/input/input4/uevent`, but this file is empty
unexpectedly.

Then ,I searched on the web about this and found a bug opened in
2016-05-24 by Markus:
https://bugzilla.kernel.org/show_bug.cgi?id=118861
The status of this bug is still NEW.

I tried to debug the kernel. And I got something that may be useful.
The "uevent" shows empty, because a -ENOMEM error returns by
`input_add_uevent_modalias_var`.
And this function returns -ENOMEM, because the `buf` on `struct
kobj_uevent_env` is not enough.

The size of `buf` is 2048 (UEVENT_BUFFER_SIZE). According to the
MODALIAS encoding algorithm (input_print_modalias_bits), if we allow
all 0x2ff keys to be enabled on the
uinput device, the buffer should have at least 2477 bytes. (2477 =  3
* (0xff - 0x71 + 1) + 4 * 0x200)
2048 is smaller than 2477, so it fails.

I have tried to set UEVENT_BUFFER_SIZE to 4096. After that,
everythings seems ok. The `/sys/devices/virtual/input/input4/uevent`
can show its content correctly. (See the attachment uevent.txt)

Since this change is related to the core feature kobject which is used
everywhere in the kernel, I don't know if doubling the
UEVENT_BUFFER_SIZE is the best way to fix it, or if it will cause
other serious problems.
Or maybe we can use a dynamic buffer size in `struct kobj_uevent_env`.


Thank you,
Zhai Zhaoxuan

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help