Skip to content

Commit

Permalink
(evdev) EVIOCGBIT(_, x) treat (x) as len not nbits
Browse files Browse the repository at this point in the history
The history and tracking for this one seem to be an interesting rabbit
hole if you are absolutely bored with life but not bored with bittwiddle
syscall interfaces written in an era where every bit is precious and
64 bit memory not a thing for the commoners.

As far as memory serves this was initially written from documentation
that treated the len field being the number of bits and not the size of
the destination buffer. The same detail can be found piecewise in
Android suggesting that I was not hallucinating the entire time.

The kernel interface however treats this as the buffer size (so we are
in multiples of 8 wrong in the one direction or the other) and this
likely triggered on FreeBSDs implementation of evdev which explicitly
bzeroes up to len, 0ing up the stack - otherwise it would only be
visible on devices with a whole lot of keys. It also looks like other
consumers of the interface just yolo overallocates instead.
  • Loading branch information
letoram committed Sep 30, 2023
1 parent 8578606 commit 9020c03
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions src/platform/evdev/event.c
Expand Up @@ -313,7 +313,7 @@ static bool identify(int fd, const char* path,
/* even this point has a few collisions, particularly some keyboards and mice
* that don't respond to CGUNIQ and expose multiple- subdevices but with
* different button/axis count */
ioctl(fd, EVIOCGBIT(0, EV_MAX), &buf);
ioctl(fd, EVIOCGBIT(0, sizeof(buf)), &buf);
}

for (size_t i = 0; i < sizeof(buf); i++)
Expand Down Expand Up @@ -849,7 +849,7 @@ static size_t button_count(int fd, size_t bitn, bool* got_mouse, bool* got_joy)

unsigned long bits[ bit_count(KEY_MAX) ];

if (-1 == ioctl(fd, EVIOCGBIT(bitn, KEY_MAX), bits))
if (-1 == ioctl(fd, EVIOCGBIT(bitn, sizeof(bits)), bits))
return false;

for (size_t i = 0; i < KEY_MAX; i++){
Expand All @@ -870,7 +870,7 @@ static size_t button_count(int fd, size_t bitn, bool* got_mouse, bool* got_joy)
static bool check_mouse_axis(int fd, size_t bitn)
{
unsigned long bits[ bit_count(KEY_MAX) ];
if (-1 == ioctl(fd, EVIOCGBIT(bitn, KEY_MAX), bits))
if (-1 == ioctl(fd, EVIOCGBIT(bitn, sizeof(bits)), bits))
return false;

/* uncertain if other (REL_Z, REL_RX, REL_RY, REL_RZ, REL_DIAL, REL_MISC)
Expand Down Expand Up @@ -921,15 +921,15 @@ static void map_axes(int fd, size_t bitn, struct devnode* node)
return;
node->game.axes = 0;

if (-1 != ioctl(fd, EVIOCGBIT(bitn, ABS_MAX), bits)){
if (-1 != ioctl(fd, EVIOCGBIT(bitn, sizeof(bits)), bits)){
for (size_t i = 0; i < ABS_MAX; i++){
if (bit_isset(bits, i))
node->game.axes++;
}
}

node->game.relofs = node->game.axes;
if (-1 != ioctl(fd, EVIOCGBIT(bitn, REL_MAX), rel_bits)){
if (-1 != ioctl(fd, EVIOCGBIT(bitn, sizeof(rel_bits)), rel_bits)){
for (size_t i = 0; i < REL_MAX; i++){
if (bit_isset(bits, i)){
node->game.axes++;
Expand Down Expand Up @@ -971,7 +971,7 @@ static void map_axes(int fd, size_t bitn, struct devnode* node)
static void setup_led(struct devnode* dst, size_t bitn, int fd)
{
unsigned long bits[ bit_count(LED_MAX) ];
if (-1 == ioctl(fd, EVIOCGBIT(bitn, LED_MAX), bits))
if (-1 == ioctl(fd, EVIOCGBIT(bitn, sizeof(bits)), bits))
return;

size_t count = 0;
Expand Down Expand Up @@ -1296,7 +1296,7 @@ static void got_device(struct arcan_evctx* ctx, int fd, const char* path)
size_t nbits = ((EV_MAX)-1) / bpl + 1;
long prop[ nbits ];

if (-1 == ioctl(fd, EVIOCGBIT(0, EV_MAX), &prop)){
if (-1 == ioctl(fd, EVIOCGBIT(0, sizeof(prop)), &prop)){
verbose_print(
"input: probing %s failed, %s", path, strerror(errno));
close(fd);
Expand Down

0 comments on commit 9020c03

Please sign in to comment.