Received: by 2002:a25:31c3:0:0:0:0:0 with SMTP id x186csp6546298ybx; Mon, 11 Nov 2019 10:43:45 -0800 (PST) X-Google-Smtp-Source: APXvYqzWaANr8Eyvzkw+bKKg8hriirmIHpHLEzy7JbAvtmXEAJ2ZAVG4TZ7mL8DMwMiAMxDI3nqS X-Received: by 2002:aa7:db52:: with SMTP id n18mr27147871edt.169.1573497825168; Mon, 11 Nov 2019 10:43:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573497825; cv=none; d=google.com; s=arc-20160816; b=uvLTac9OzCA8B4w6hnCF+TTubEyN9YAODkoM6M05fUaUR5eJz3OPkI6G8X58dxvmfO sZeX9O3DMiGFtdN5r7/GwkW26tLGfahn+tvz6GfHCjnknKqjcgA8tJ8hN0sSZ500sPHG u5gaa3vQu3ArgyNs3A3GEttqGo70HwyvfD16amxcMUVUG6chZxbY+wZPQEmsXrmBd929 dDlX9JxnmEvks0GtHvXHI1IXyN1zBT7ZuqBQvCtdsvaALn5iramv7P/+Ol48SO/+55HY qD627UvKEFHpgtN0RDHgXECcy9Rv186HxC6J0jeIekFl3QnPbJI1+yiAAN2QGTZz9AX/ Zfwg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=xDCC9Ps/vtSREArZ/h7jUmTWnu7GpliKr2mxtqcI8tU=; b=bw6dhhCroHJwjISiKuJ7ysc0sO3KF+OWSSBrfAZkyEzTzOEWcTipQkWX8N55drZn4/ gjtkCfSljM+FzKtNkxExuLi/0hY7qbbCbBBQ3dVe08YkZtOx+o68XYPuubaekK+rHlrS kgoJA9jt7HFtyvJ1wrEeQ/lNxGMjGnAIM1fgxdE8WqPlcBdEhaGWvzy/KcrAPp+iAw/u ES0U2zdGLfPZ/fNMz7X/7U+rkKycCaSN1Rl1obAeYo4q1crIwho71B5jKvepGIDzViL6 0Af0m/C1QkxVOVkklfGPPbcDdC4SfRRIcGLjWFTeervL+gN6sM5ATFKB/70+hL08E3fS B9mQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=xiLujU4a; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u24si12773072edl.447.2019.11.11.10.43.21; Mon, 11 Nov 2019 10:43:45 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=xiLujU4a; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729388AbfKKSl3 (ORCPT + 99 others); Mon, 11 Nov 2019 13:41:29 -0500 Received: from mail.kernel.org ([198.145.29.99]:60704 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729382AbfKKSl1 (ORCPT ); Mon, 11 Nov 2019 13:41:27 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id A1246214E0; Mon, 11 Nov 2019 18:41:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1573497686; bh=ZDHWvVUEmYT+jl6ofwxF/rKHKUtBYAfktmiVE3OZC80=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=xiLujU4aWl7FXcmn1y1PWzaMuc3l/DsJoMAtbcosqIoGbY1aayrNcx42F2W93vHEU lyNwtZGnZiHtVuDni+02oPaBvDsYUOlhfVAq+C7oEBr6ZByZhCeLYOaP50cH4u8V1c KkzeYkgungDOduQvnGiBRvlfijihWAhVoC04ZMxw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jason Gerecke , Aaron Armstrong Skomra , Jiri Kosina Subject: [PATCH 4.19 027/125] HID: wacom: generic: Treat serial number and related fields as unsigned Date: Mon, 11 Nov 2019 19:27:46 +0100 Message-Id: <20191111181444.186103315@linuxfoundation.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191111181438.945353076@linuxfoundation.org> References: <20191111181438.945353076@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jason Gerecke commit ff479731c3859609530416a18ddb3db5db019b66 upstream. 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: # v4.10+ Signed-off-by: Jason Gerecke Reviewed-by: Aaron Armstrong Skomra Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/wacom.h | 15 +++++++++++++++ drivers/hid/wacom_wac.c | 10 ++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -205,6 +205,21 @@ static inline void wacom_schedule_work(s } } +/* + * 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); --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2271,7 +2271,7 @@ static void wacom_wac_pen_event(struct h 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: @@ -2287,15 +2287,17 @@ static void wacom_wac_pen_event(struct h 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; @@ -2307,7 +2309,7 @@ static void wacom_wac_pen_event(struct h * 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)