Package: udev Version: 175-3 Severity: normal Tags: patch Remapping with /lib/udev/keymap doesn't work correctly when a key name starts with a digit, like 102nd, which appears in "/usr/include/linux/input.h":
#define KEY_102ND 86 In such a case, the number that appears as the prefix (here 102) is used as the key code. The bug is here: if (sscanf(p, "%i %i", &scancode, &new_keycode) != 2) { as it doesn't check what follows the second integer. I propose the attached patch. For instance, when I wanted to use the following key map file in order to exchange two keys: 0x70035 102nd 0x70064 grave but I got: $ sudo /lib/udev/keymap input/event17 ~/keymap.apple Remapped scancode 0x70035 to 0x66 (prior: 0x29) Remapped scancode 0x70064 to 0x29 (prior: 0x56) with 0x66 instead of 0x56. But typing key 0x70064 then produced the X keycode 110 keysym Home (according to xev) and 0x70035 had no effect. This is a strange behavior (according to the printed information, I would have expected 0x70064 to be correct, not to use the keycode configured for 0x70035), but after some tests, it just seems that the driver is confused when I use two scan codes with the same key code. -- System Information: Debian Release: wheezy/sid APT prefers unstable APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental') Architecture: amd64 (x86_64) Kernel: Linux 3.1.0-1-amd64 (SMP w/2 CPU cores) Locale: LANG=POSIX, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages udev depends on: ii debconf [debconf-2.0] 1.5.41 ii libc6 2.13-24 ii libselinux1 2.1.0-4 ii libudev0 175-3 ii lsb-base 3.2-28 ii util-linux 2.20.1-1.1 Versions of packages udev recommends: ii pciutils 1:3.1.8-2 ii usbutils 1:005-2 udev suggests no packages. -- debconf information: udev/new_kernel_needed: false udev/title/upgrade: udev/reboot_needed: udev/sysfs_deprecated_incompatibility:
--- udev-175/extras/keymap/keymap.c 2011-08-28 20:45:33.000000000 +0000 +++ udev-new/extras/keymap/keymap.c 2012-01-07 01:41:54.000000000 +0000 @@ -191,6 +191,7 @@ while (!feof(f)) { char s[256], *p; int scancode, new_keycode, old_keycode; + int n; if (!fgets(s, sizeof(s), f)) break; @@ -200,7 +201,7 @@ if (*p == '#' || *p == '\n') continue; - if (sscanf(p, "%i %i", &scancode, &new_keycode) != 2) { + if (sscanf(p, "%i %i%n", &scancode, &new_keycode, &n) < 2 || (p[n] != '\t' && p[n] != ' ' && p[n] != '#' && p[n] != '\n')) { char t[105] = "KEY_UNKNOWN"; const struct key *k;