All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] HID: wacom: generic: Treat serial number and related fields as unsigned
@ 2019-11-06 19:59 Gerecke, Jason
  2019-11-06 20:38 ` Jiri Kosina
  0 siblings, 1 reply; 2+ messages in thread
From: Gerecke, Jason @ 2019-11-06 19:59 UTC (permalink / raw)
  To: linux-input, Jiri Kosina, Benjamin Tissoires
  Cc: Ping Cheng, Aaron Armstrong Skomra, Jason Gerecke, stable,
	Jason Gerecke, Aaron Armstrong Skomra

From: Jason Gerecke <killertofu@gmail.com>

The HID descriptors for most Wacom devices oddly declare the serial
number and other related fields as signed integers. When these numbers
are ingested by the HID subsystem, they are automatically sign-extended
into 32-bit integers. We treat the fields as unsigned elsewhere in the
kernel and userspace, however, so this sign-extension causes problems.
In particular, the sign-extended tool ID sent to userspace as ABS_MISC
does not properly match unsigned IDs used by xf86-input-wacom and libwacom.

We introduce a function 'wacom_s32tou' that can undo the automatic sign
extension performed by 'hid_snto32'. We call this function when processing
the serial number and related fields to ensure that we are dealing with
and reporting the unsigned form. We opt to use this method rather than
adding a descriptor fixup in 'wacom_hid_usage_quirk' since it should be
more robust in the face of future devices.

Ref: https://github.com/linuxwacom/input-wacom/issues/134
Fixes: f85c9dc678 ("HID: wacom: generic: Support tool ID and additional tool types")
CC: <stable@vger.kernel.org> # v4.10+
Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
Reviewed-by: Aaron Armstrong Skomra <aaron.skomra@wacom.com>
---
 drivers/hid/wacom.h     | 15 +++++++++++++++
 drivers/hid/wacom_wac.c | 10 ++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h
index 4a7f8d363220..203d27d198b8 100644
--- a/drivers/hid/wacom.h
+++ b/drivers/hid/wacom.h
@@ -202,6 +202,21 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac,
 	}
 }
 
+/*
+ * Convert a signed 32-bit integer to an unsigned n-bit integer. Undoes
+ * the normally-helpful work of 'hid_snto32' for fields that use signed
+ * ranges for questionable reasons.
+ */
+static inline __u32 wacom_s32tou(s32 value, __u8 n)
+{
+	switch (n) {
+	case 8:  return ((__u8)value);
+	case 16: return ((__u16)value);
+	case 32: return ((__u32)value);
+	}
+	return value & (1 << (n - 1)) ? value & (~(~0U << n)) : value;
+}
+
 extern const struct hid_device_id wacom_ids[];
 
 void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 2b0a5b8ca6e6..ccb74529bc78 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -2303,7 +2303,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
 	case HID_DG_TOOLSERIALNUMBER:
 		if (value) {
 			wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL);
-			wacom_wac->serial[0] |= (__u32)value;
+			wacom_wac->serial[0] |= wacom_s32tou(value, field->report_size);
 		}
 		return;
 	case HID_DG_TWIST:
@@ -2319,15 +2319,17 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
 		return;
 	case WACOM_HID_WD_SERIALHI:
 		if (value) {
+			__u32 raw_value = wacom_s32tou(value, field->report_size);
+
 			wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF);
-			wacom_wac->serial[0] |= ((__u64)value) << 32;
+			wacom_wac->serial[0] |= ((__u64)raw_value) << 32;
 			/*
 			 * Non-USI EMR devices may contain additional tool type
 			 * information here. See WACOM_HID_WD_TOOLTYPE case for
 			 * more details.
 			 */
 			if (value >> 20 == 1) {
-				wacom_wac->id[0] |= value & 0xFFFFF;
+				wacom_wac->id[0] |= raw_value & 0xFFFFF;
 			}
 		}
 		return;
@@ -2339,7 +2341,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
 		 * bitwise OR so the complete value can be built
 		 * up over time :(
 		 */
-		wacom_wac->id[0] |= value;
+		wacom_wac->id[0] |= wacom_s32tou(value, field->report_size);
 		return;
 	case WACOM_HID_WD_OFFSETLEFT:
 		if (features->offset_left && value != features->offset_left)
-- 
2.23.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] HID: wacom: generic: Treat serial number and related fields as unsigned
  2019-11-06 19:59 [PATCH] HID: wacom: generic: Treat serial number and related fields as unsigned Gerecke, Jason
@ 2019-11-06 20:38 ` Jiri Kosina
  0 siblings, 0 replies; 2+ messages in thread
From: Jiri Kosina @ 2019-11-06 20:38 UTC (permalink / raw)
  To: Gerecke, Jason
  Cc: linux-input, Benjamin Tissoires, Ping Cheng,
	Aaron Armstrong Skomra, stable, Jason Gerecke,
	Aaron Armstrong Skomra

On Wed, 6 Nov 2019, Gerecke, Jason wrote:

> From: Jason Gerecke <killertofu@gmail.com>
> 
> The HID descriptors for most Wacom devices oddly declare the serial
> number and other related fields as signed integers. When these numbers
> are ingested by the HID subsystem, they are automatically sign-extended
> into 32-bit integers. We treat the fields as unsigned elsewhere in the
> kernel and userspace, however, so this sign-extension causes problems.
> In particular, the sign-extended tool ID sent to userspace as ABS_MISC
> does not properly match unsigned IDs used by xf86-input-wacom and libwacom.
> 
> We introduce a function 'wacom_s32tou' that can undo the automatic sign
> extension performed by 'hid_snto32'. We call this function when processing
> the serial number and related fields to ensure that we are dealing with
> and reporting the unsigned form. We opt to use this method rather than
> adding a descriptor fixup in 'wacom_hid_usage_quirk' since it should be
> more robust in the face of future devices.
> 
> Ref: https://github.com/linuxwacom/input-wacom/issues/134
> Fixes: f85c9dc678 ("HID: wacom: generic: Support tool ID and additional tool types")
> CC: <stable@vger.kernel.org> # v4.10+
> Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
> Reviewed-by: Aaron Armstrong Skomra <aaron.skomra@wacom.com>

Applied to for-5.4/upstream-fixes.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-11-06 20:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-06 19:59 [PATCH] HID: wacom: generic: Treat serial number and related fields as unsigned Gerecke, Jason
2019-11-06 20:38 ` Jiri Kosina

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.