keyboard LED bug + patch
Peter Hutterer
peter.hutterer at who-t.net
Thu Apr 30 23:22:35 PDT 2009
On Sat, Feb 28, 2009 at 12:53:10AM -0500, pacman at kosh.dhis.org wrote:
> The component: xf86-input-keyboard
>
> The source file: src/lnx_kbd.c
>
> The function: GetKbdLeds
>
> The bug:
> int real_leds, leds = 0;
>
> ioctl(pInfo->fd, KDGETLED, &real_leds);
>
> if (real_leds & LED_CAP) leds |= XLED1;
> if (real_leds & LED_NUM) leds |= XLED2;
> if (real_leds & LED_SCR) leds |= XLED3;
>
> The reason:
> KDGETLED actually only stores a single byte at the address indicated by
> &real_leds, which on big-endian systems means the kernel's led state is put
> into the most-significant byte of real_leds. The LED_CAP LED_NUM LED_SCR
> macros then extract some bits from the least-significant byte, which still
> contains stack garbage since real_leds hasn't been initialized.
>
> Don't believe what the console_ioctl(4) man page says. It's wrong. Go read
> drivers/char/vt_ioctl.c in the kernel source, or run this demo on a
> big-endian machine:
>
> #include <stdio.h>
> #include <sys/ioctl.h>
> #include <linux/kd.h>
>
> int main(void)
> {
> int ioctlret;
> long longval;
>
> longval = -1;
>
> ioctlret = ioctl(0, KDGETLED, &longval);
> printf("ioctlret=%d longval=%08lx\n", ioctlret, longval);
>
> return 0;
> }
>
> The fix is very simple:
>
> diff --git a/src/lnx_kbd.c b/src/lnx_kbd.c
> index cfe35a3..9144464 100644
> --- a/src/lnx_kbd.c
> +++ b/src/lnx_kbd.c
> @@ -73,7 +73,8 @@ SetKbdLeds(InputInfoPtr pInfo, int leds)
> static int
> GetKbdLeds(InputInfoPtr pInfo)
> {
> - int real_leds, leds = 0;
> + char real_leds;
> + int leds = 0;
>
> ioctl(pInfo->fd, KDGETLED, &real_leds);
>
Pushed, thanks for the patch.
Cheers,
Peter
More information about the xorg-devel
mailing list