LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Adam Goode <adam@spicenitz.org>,
	Fredrik Hallenberg <megahallon@gmail.com>,
	David Herrmann <dh.herrmann@gmail.com>,
	Jiri Kosina <jkosina@suse.cz>
Subject: [PATCH 3.10 57/62] HID: input: fix confusion on conflicting mappings
Date: Mon, 16 Mar 2015 15:10:14 +0100	[thread overview]
Message-ID: <20150316140935.756677603@linuxfoundation.org> (raw)
In-Reply-To: <20150316140933.139548981@linuxfoundation.org>

3.10-stable review patch.  If anyone has any objections, please let me know.

------------------

From: David Herrmann <dh.herrmann@gmail.com>

commit 6ce901eb61aa30ba8565c62049ee80c90728ef14 upstream.

On an PC-101/103/104 keyboard (American layout) the 'Enter' key and its
neighbours look like this:

           +---+ +---+ +-------+
           | 1 | | 2 | |   5   |
           +---+ +---+ +-------+
             +---+ +-----------+
             | 3 | |     4     |
             +---+ +-----------+

On a PC-102/105 keyboard (European layout) it looks like this:

           +---+ +---+ +-------+
           | 1 | | 2 | |       |
           +---+ +---+ +-+  4  |
             +---+ +---+ |     |
             | 3 | | 5 | |     |
             +---+ +---+ +-----+

(Note that the number of keys is the same, but key '5' is moved down and
 the shape of key '4' is changed. Keys '1' to '3' are exactly the same.)

The keys 1-4 report the same scan-code in HID in both layouts, even though
the keysym they produce is usually different depending on the XKB-keymap
used by user-space.
However, key '5' (US 'backslash'/'pipe') reports 0x31 for the upper layout
and 0x32 for the lower layout, as defined by the HID spec. This is highly
confusing as the linux-input API uses a single keycode for both.

So far, this was never a problem as there never has been a keyboard with
both of those keys present at the same time. It would have to look
something like this:

           +---+ +---+ +-------+
           | 1 | | 2 | |  x31  |
           +---+ +---+ +-------+
             +---+ +---+ +-----+
             | 3 | |x32| |  4  |
             +---+ +---+ +-----+

HID can represent such a keyboard, but the linux-input API cannot.
Furthermore, any user-space mapping would be confused by this and,
luckily, no-one ever produced such hardware.

Now, the HID input layer fixed this mess by mapping both 0x31 and 0x32 to
the same keycode (KEY_BACKSLASH==0x2b). As only one of both physical keys
is present on a hardware, this works just fine.

Lets introduce hardware-vendors into this:
------------------------------------------

Unfortunately, it seems way to expensive to produce a different device for
American and European layouts. Therefore, hardware-vendors put both keys,
(0x31 and 0x32) on the same keyboard, but only one of them is hooked up
to the physical button, the other one is 'dead'.
This means, they can use the same hardware, with a different button-layout
and automatically produce the correct HID events for American *and*
European layouts. This is unproblematic for normal keyboards, as the
'dead' key will never report any KEY-DOWN events. But RollOver keyboards
send the whole matrix on each key-event, allowing n-key roll-over mode.
This means, we get a 0x31 and 0x32 event on each key-press. One of them
will always be 0, the other reports the real state. As we map both to the
same keycode, we will get spurious key-events, even though the real
key-state never changed.

The easiest way would be to blacklist 'dead' keys and never handle those.
We could simply read the 'country' tag of USB devices and blacklist either
key according to the layout. But... hardware vendors... want the same
device for all countries and thus many of them set 'country' to 0 for all
devices. Meh..

So we have to deal with this properly. As we cannot know which of the keys
is 'dead', we either need a heuristic and track those keys, or we simply
make use of our value-tracking for HID fields. We simply ignore HID events
for absolute data if the data didn't change. As HID tracks events on the
HID level, we haven't done the keycode translation, yet. Therefore, the
'dead' key is tracked independently of the real key, therefore, any events
on it will be ignored.

This patch simply discards any HID events for absolute data if it didn't
change compared to the last report. We need to ignore relative and
buffered-byte reports for obvious reasons. But those cannot be affected by
this bug, so we're fine.

Preferably, we'd do this filtering on the HID-core level. But this might
break a lot of custom drivers, if they do not follow the HID specs.
Therefore, we do this late in hid-input just before we inject it into the
input layer (which does the exact same filtering, but on the keycode
level).

If this turns out to break some devices, we might have to limit filtering
to EV_KEY events. But lets try to do the Right Thing first, and properly
filter any absolute data that didn't change.

This patch is tagged for 'stable' as it fixes a lot of n-key RollOver
hardware. We might wanna wait with backporting for a while, before we know
it doesn't break anything else, though.

Reported-by: Adam Goode <adam@spicenitz.org>
Reported-by: Fredrik Hallenberg <megahallon@gmail.com>
Tested-by: Fredrik Hallenberg <megahallon@gmail.com>
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 drivers/hid/hid-input.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)

--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1066,6 +1066,22 @@ void hidinput_hid_event(struct hid_devic
 		return;
 	}
 
+	/*
+	 * Ignore reports for absolute data if the data didn't change. This is
+	 * not only an optimization but also fixes 'dead' key reports. Some
+	 * RollOver implementations for localized keys (like BACKSLASH/PIPE; HID
+	 * 0x31 and 0x32) report multiple keys, even though a localized keyboard
+	 * can only have one of them physically available. The 'dead' keys
+	 * report constant 0. As all map to the same keycode, they'd confuse
+	 * the input layer. If we filter the 'dead' keys on the HID level, we
+	 * skip the keycode translation and only forward real events.
+	 */
+	if (!(field->flags & (HID_MAIN_ITEM_RELATIVE |
+	                      HID_MAIN_ITEM_BUFFERED_BYTE)) &&
+	    usage->usage_index < field->maxusage &&
+	    value == field->value[usage->usage_index])
+		return;
+
 	/* report the usage code as scancode if the key status has changed */
 	if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
 		input_event(input, EV_MSC, MSC_SCAN, usage->hid);



  parent reply	other threads:[~2015-03-16 14:32 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-16 14:09 [PATCH 3.10 00/62] 3.10.72-stable review Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 01/62] rtnetlink: ifla_vf_policy: fix misuses of NLA_BINARY Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 02/62] ipv6: fix ipv6_cow_metrics for non DST_HOST case Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 03/62] rtnetlink: call ->dellink on failure when ->newlink exists Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 05/62] ipv4: ip_check_defrag should correctly check return value of skb_copy_bits Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 06/62] ipv4: ip_check_defrag should not assume that skb_network_offset is zero Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 07/62] net: phy: Fix verification of EEE support in phy_init_eee Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 09/62] net: reject creation of netdev names with colons Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 10/62] team: fix possible null pointer dereference in team_handle_frame Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 11/62] net: compat: Ignore MSG_CMSG_COMPAT in compat_sys_{send, recv}msg Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 12/62] macvtap: make sure neighbour code can push ethernet header Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 13/62] usb: plusb: Add support for National Instruments host-to-host cable Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 14/62] udp: only allow UFO for packets from SOCK_DGRAM sockets Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 15/62] team: dont traverse port list using rcu in team_set_mac_address Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 16/62] mm/hugetlb: add migration entry check in __unmap_hugepage_range Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 17/62] mm/mmap.c: fix arithmetic overflow in __vm_enough_memory() Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 18/62] mm/nommu.c: " Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 19/62] mm/compaction: fix wrong order check in compact_finished() Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 20/62] mm/memory.c: actually remap enough memory Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 21/62] target: Check for LBA + sectors wrap-around in sbc_parse_cdb Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 22/62] PM / QoS: remove duplicate call to pm_qos_update_target Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 23/62] x86/asm/entry/64: Remove a bogus ret_from_fork optimization Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 24/62] iio: imu: adis16400: Fix sign extension Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 25/62] btrfs: fix lost return value due to variable shadowing Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 26/62] Btrfs: fix data loss in the fast fsync path Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 27/62] Btrfs:__add_inode_ref: out of bounds memory read when looking for extended ref Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 28/62] KVM: emulate: fix CMPXCHG8B on 32-bit hosts Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 29/62] KVM: MIPS: Fix trace event to save PC directly Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 30/62] USB: serial: cp210x: Adding Seletek device ids Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 31/62] USB: usbfs: dont leak kernel data in siginfo Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 32/62] usb: ftdi_sio: Add jtag quirk support for Cyber Cortex AV boards Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 33/62] xhci: Allocate correct amount of scratchpad buffers Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 34/62] xhci: fix reporting of 0-sized URBs in control endpoint Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 35/62] net: irda: fix wait_until_sent poll timeout Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 36/62] USB: serial: fix infinite wait_until_sent timeout Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 37/62] TTY: fix tty_wait_until_sent on 64-bit machines Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 38/62] USB: serial: fix potential use-after-free after failed probe Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 39/62] autofs4 copy_dev_ioctl(): keep the value of ->size wed used for allocation Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 40/62] debugfs: leave freeing a symlink body until inode eviction Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 41/62] procfs: fix race between symlink removals and traversals Greg Kroah-Hartman
2015-03-16 14:09 ` [PATCH 3.10 42/62] sunrpc: fix braino in ->poll() Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 43/62] tty: fix up atime/mtime mess, take four Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 44/62] ALSA: pcm: Dont leave PREPARED state after draining Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 45/62] ALSA: hda - Add pin configs for ASUS mobo with IDT 92HD73XX codec Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 46/62] sg: fix read() error reporting Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 47/62] IB/qib: Do not write EEPROM Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 48/62] nilfs2: fix potential memory overrun on inode Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 49/62] fixed invalid assignment of 64bit mask to host dma_boundary for scatter gather segment boundary limit Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 50/62] clk: sunxi: Support factor clocks with N factor starting not from 0 Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 51/62] staging: comedi: comedi_compat32.c: fix COMEDI_CMD copy back Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 52/62] dm mirror: do not degrade the mirror on discard error Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 53/62] dm io: reject unsupported DISCARD requests with EOPNOTSUPP Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 54/62] dm: fix a race condition in dm_get_md Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 55/62] dm snapshot: fix a possible invalid memory access on unload Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 56/62] staging: comedi: cb_pcidas64: fix incorrect AI range code handling Greg Kroah-Hartman
2015-03-16 14:10 ` Greg Kroah-Hartman [this message]
2015-03-16 14:10 ` [PATCH 3.10 58/62] HID: fixup the conflicting keyboard mappings quirk Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 60/62] drm/radeon: fix 1 RB harvest config setup for TN/RL Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 61/62] ACPI / video: Load the module even if ACPI is disabled Greg Kroah-Hartman
2015-03-16 14:10 ` [PATCH 3.10 62/62] ath5k: fix spontaneus AR5312 freezes Greg Kroah-Hartman
2015-03-16 19:57 ` [PATCH 3.10 00/62] 3.10.72-stable review Guenter Roeck
2015-03-17 17:01 ` Masanari Iida
2015-03-17 20:44   ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150316140935.756677603@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=adam@spicenitz.org \
    --cc=dh.herrmann@gmail.com \
    --cc=jkosina@suse.cz \
    --cc=linux-kernel@vger.kernel.org \
    --cc=megahallon@gmail.com \
    --cc=stable@vger.kernel.org \
    --subject='Re: [PATCH 3.10 57/62] HID: input: fix confusion on conflicting mappings' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).