@@ -966,9 +966,6 @@ static inline void hid_map_usage(struct hid_input *hidinput,
{
struct input_dev *input = hidinput->input;
- usage->type = type;
- usage->code = c;
-
switch (type) {
case EV_ABS:
*bit = input->absbit;
@@ -986,7 +983,20 @@ static inline void hid_map_usage(struct hid_input *hidinput,
*bit = input->ledbit;
*max = LED_MAX;
break;
+ default:
+ *bit = NULL;
+ *max = 0;
+ usage->code = 0;
+ usage->type = 0;
+ return;
}
+
+ usage->type = type;
+ usage->code = c & *max;
+
+ if (unlikely(usage->code != c))
+ pr_warn_ratelimited("%s: Truncated code %d to %d for type %d\n",
+ input->name, c, usage->code, type);
}
/**
@@ -1000,7 +1010,8 @@ static inline void hid_map_usage_clear(struct hid_input *hidinput,
__u8 type, __u16 c)
{
hid_map_usage(hidinput, usage, bit, max, type, c);
- clear_bit(c, *bit);
+ if (*bit)
+ clear_bit(usage->code, *bit);
}
/**
When calling into hid_map_usage(), the passed event code is blindly stored as is, even if it doesn't fit in the associated bitmap. This event code can come from a variety of sources, including devices masquerading as input devices, only a bit more "programmable". Instead of taking the raw event code, sanitize it to the actual bitmap size and output a warning to let the user know. While we're at it, sanitize the hid_usage structure if the type isn't known, conveniently placing a NULL pointer as the bitmap in order to catch unexpected uses. Cc: stable@vger.kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org> --- include/linux/hid.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)