From nobody Mon May 4 13:04:16 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B1A8289E13; Mon, 4 May 2026 08:47:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777884467; cv=none; b=jO6cn3ooNEWQGM5umMzmefGx21CK6XlFu6uU4xClRpMmcNGAllMhyXUwAKmTPYWVDY85uwTwidNZFTvFa+tjH+92Q2KhR/z4Ws2EM6JCa0HHJUrGJPV6NdGPfDiXHtor3Ax+N6dYysNkivDi2hlGl0PU+/n+JWvzzqol7XBHVt8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777884467; c=relaxed/simple; bh=reisxM18eCL19FOaJMFN/f2bXoQctsrOeIQ8jJyyWX8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=u0hQX+5C3XacMhckFPVfYDqXvXyI8ogFnZ1Ov3V8wxngUeTqkbIEiqA4eH5uvotcDX3wpxAwdHL6yjg1DtNlaTGIeu6av3z0yAYmlGQF0brgxaMov8dD0ReFyGZx35GC9JdAe2qFcDpCcI9PmBCjCc5Zoh64tRyuaNmDa/gsLms= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ct4jtIT1; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ct4jtIT1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9F79CC2BCB8; Mon, 4 May 2026 08:47:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777884467; bh=reisxM18eCL19FOaJMFN/f2bXoQctsrOeIQ8jJyyWX8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Ct4jtIT1DelsMs9eAl+MukHC8TNOs8YQtJtNnNBlct/X6dk+2axIZRMi2ltBsKhKS JUVEBkd6RxM7Gq842s//qOkWUNSKA5MNRo9xicl8BUA6BBpLuYA5aw/ivKmcPhb35c bZGgihPEdo3aqpQDhdQx8ZVsohnHtKSsABSTidjnmACNCWUKMYwJzSd0hVGRRWQ3ta g4v1iNKPFnsedbw8aBYsoBP4Hg7VSBctHhfxxRiRZgLPt6lBMAhhqhkCNu4GyIShan 1RZDw7ZeR+YpVKNLeR6hj/ZWyNP5N2Im8a+xAH5HpvWm4GKO3NYkYT/WRwJWnmWw7e JcQhUNvgyBlmg== From: Benjamin Tissoires Date: Mon, 04 May 2026 10:47:22 +0200 Subject: [PATCH v3 1/4] HID: pass the buffer size to hid_report_raw_event Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-wip-fix-core-v3-1-ce1f11f4968f@kernel.org> References: <20260504-wip-fix-core-v3-0-ce1f11f4968f@kernel.org> In-Reply-To: <20260504-wip-fix-core-v3-0-ce1f11f4968f@kernel.org> To: Jiri Kosina , =?utf-8?q?Filipe_La=C3=ADns?= , Bastien Nocera , Ping Cheng , Jason Gerecke , Viresh Kumar , Johan Hovold , Alex Elder , Greg Kroah-Hartman , Lee Jones Cc: Icenowy Zheng , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, greybus-dev@lists.linaro.org, linux-staging@lists.linux.dev, linux-usb@vger.kernel.org, Benjamin Tissoires , stable@vger.kernel.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1777884459; l=13915; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=reisxM18eCL19FOaJMFN/f2bXoQctsrOeIQ8jJyyWX8=; b=A9sR9z4YY3IL3AAxmMJMNaY7aiiXJdGuJ7gy6wnAHK32wg8fUJcuFJYNGc/P0wTvMaVXPlQBx azu78nkvkffBB31khwbyFGAMf9/NvgutiQ5WCLmcm8wm98VUYpxFqQg X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()") enforced the provided data to be at least the size of the declared buffer in the report descriptor to prevent a buffer overflow. However, we can try to be smarter by providing both the buffer size and the data size, meaning that hid_report_raw_event() can make better decision whether we should plaining reject the buffer (buffer overflow attempt) or if we can safely memset it to 0 and pass it to the rest of the stack. Fixes: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus m= emset()") Cc: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires Acked-by: Johan Hovold Reviewed-by: Greg Kroah-Hartman --- drivers/hid/bpf/hid_bpf_dispatch.c | 6 ++++-- drivers/hid/hid-core.c | 42 +++++++++++++++++++++++++---------= ---- drivers/hid/hid-gfrm.c | 4 ++-- drivers/hid/hid-logitech-hidpp.c | 2 +- drivers/hid/hid-multitouch.c | 2 +- drivers/hid/hid-primax.c | 2 +- drivers/hid/hid-vivaldi-common.c | 2 +- drivers/hid/wacom_sys.c | 6 +++--- drivers/staging/greybus/hid.c | 2 +- include/linux/hid.h | 4 ++-- include/linux/hid_bpf.h | 14 ++++++++----- 11 files changed, 53 insertions(+), 33 deletions(-) diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_d= ispatch.c index 50c7b45c59e3..d0130658091b 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -24,7 +24,8 @@ EXPORT_SYMBOL(hid_ops); =20 u8 * dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_typ= e type, u8 *data, - u32 *size, int interrupt, u64 source, bool from_bpf) + size_t *buf_size, u32 *size, int interrupt, u64 source, + bool from_bpf) { struct hid_bpf_ctx_kern ctx_kern =3D { .ctx =3D { @@ -74,6 +75,7 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, en= um hid_report_type type *size =3D ret; } =20 + *buf_size =3D ctx_kern.ctx.allocated_size; return ctx_kern.data; } EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event); @@ -505,7 +507,7 @@ __hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hi= d_report_type type, u8 *b if (ret) return ret; =20 - return hid_ops->hid_input_report(ctx->hid, type, buf, size, 0, (u64)(long= )ctx, true, + return hid_ops->hid_input_report(ctx->hid, type, buf, size, size, 0, (u64= )(long)ctx, true, lock_already_taken); } =20 diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 61afec5915ec..a806820df7e5 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2033,24 +2033,32 @@ int __hid_request(struct hid_device *hid, struct hi= d_report *report, } EXPORT_SYMBOL_GPL(__hid_request); =20 -int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type= , u8 *data, u32 size, - int interrupt) +int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type= , u8 *data, + size_t bufsize, u32 size, int interrupt) { struct hid_report_enum *report_enum =3D hid->report_enum + type; struct hid_report *report; struct hid_driver *hdrv; int max_buffer_size =3D HID_MAX_BUFFER_SIZE; u32 rsize, csize =3D size; + size_t bsize =3D bufsize; u8 *cdata =3D data; int ret =3D 0; =20 report =3D hid_get_report(report_enum, data); if (!report) - goto out; + return 0; + + if (unlikely(bsize < csize)) { + hid_warn_ratelimited(hid, "Event data for report %d is incorrect (%d vs = %ld)\n", + report->id, csize, bsize); + return -EINVAL; + } =20 if (report_enum->numbered) { cdata++; csize--; + bsize--; } =20 rsize =3D hid_compute_report_size(report); @@ -2063,11 +2071,16 @@ int hid_report_raw_event(struct hid_device *hid, en= um hid_report_type type, u8 * else if (rsize > max_buffer_size) rsize =3D max_buffer_size; =20 + if (bsize < rsize) { + hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs= %ld)\n", + report->id, rsize, bsize); + return -EINVAL; + } + if (csize < rsize) { - hid_warn_ratelimited(hid, "Event data for report %d was too short (%d vs= %d)\n", - report->id, rsize, csize); - ret =3D -EINVAL; - goto out; + dbg_hid("report %d is too short, (%d < %d)\n", report->id, + csize, rsize); + memset(cdata + csize, 0, rsize - csize); } =20 if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) @@ -2075,7 +2088,7 @@ int hid_report_raw_event(struct hid_device *hid, enum= hid_report_type type, u8 * if (hid->claimed & HID_CLAIMED_HIDRAW) { ret =3D hidraw_report_event(hid, data, size); if (ret) - goto out; + return ret; } =20 if (hid->claimed !=3D HID_CLAIMED_HIDRAW && report->maxfield) { @@ -2087,15 +2100,15 @@ int hid_report_raw_event(struct hid_device *hid, en= um hid_report_type type, u8 * =20 if (hid->claimed & HID_CLAIMED_INPUT) hidinput_report_event(hid, report); -out: + return ret; } EXPORT_SYMBOL_GPL(hid_report_raw_event); =20 =20 static int __hid_input_report(struct hid_device *hid, enum hid_report_type= type, - u8 *data, u32 size, int interrupt, u64 source, bool from_bpf, - bool lock_already_taken) + u8 *data, size_t bufsize, u32 size, int interrupt, u64 source, + bool from_bpf, bool lock_already_taken) { struct hid_report_enum *report_enum; struct hid_driver *hdrv; @@ -2120,7 +2133,8 @@ static int __hid_input_report(struct hid_device *hid,= enum hid_report_type type, report_enum =3D hid->report_enum + type; hdrv =3D hid->driver; =20 - data =3D dispatch_hid_bpf_device_event(hid, type, data, &size, interrupt,= source, from_bpf); + data =3D dispatch_hid_bpf_device_event(hid, type, data, &bufsize, &size, = interrupt, + source, from_bpf); if (IS_ERR(data)) { ret =3D PTR_ERR(data); goto unlock; @@ -2149,7 +2163,7 @@ static int __hid_input_report(struct hid_device *hid,= enum hid_report_type type, goto unlock; } =20 - ret =3D hid_report_raw_event(hid, type, data, size, interrupt); + ret =3D hid_report_raw_event(hid, type, data, bufsize, size, interrupt); =20 unlock: if (!lock_already_taken) @@ -2171,7 +2185,7 @@ static int __hid_input_report(struct hid_device *hid,= enum hid_report_type type, int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8= *data, u32 size, int interrupt) { - return __hid_input_report(hid, type, data, size, interrupt, 0, + return __hid_input_report(hid, type, data, size, size, interrupt, 0, false, /* from_bpf */ false /* lock_already_taken */); } diff --git a/drivers/hid/hid-gfrm.c b/drivers/hid/hid-gfrm.c index 699186ff2349..d2a56bf92b41 100644 --- a/drivers/hid/hid-gfrm.c +++ b/drivers/hid/hid-gfrm.c @@ -66,7 +66,7 @@ static int gfrm_raw_event(struct hid_device *hdev, struct= hid_report *report, switch (data[1]) { case GFRM100_SEARCH_KEY_DOWN: ret =3D hid_report_raw_event(hdev, HID_INPUT_REPORT, search_key_dn, - sizeof(search_key_dn), 1); + sizeof(search_key_dn), sizeof(search_key_dn), 1); break; =20 case GFRM100_SEARCH_KEY_AUDIO_DATA: @@ -74,7 +74,7 @@ static int gfrm_raw_event(struct hid_device *hdev, struct= hid_report *report, =20 case GFRM100_SEARCH_KEY_UP: ret =3D hid_report_raw_event(hdev, HID_INPUT_REPORT, search_key_up, - sizeof(search_key_up), 1); + sizeof(search_key_up), sizeof(search_key_up), 1); break; =20 default: diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hi= dpp.c index b1330d23bd2d..b3ff9265377b 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -3673,7 +3673,7 @@ static int hidpp10_consumer_keys_raw_event(struct hid= pp_device *hidpp, memcpy(&consumer_report[1], &data[3], 4); /* We are called from atomic context */ hid_report_raw_event(hidpp->hid_dev, HID_INPUT_REPORT, - consumer_report, 5, 1); + consumer_report, sizeof(consumer_report), 5, 1); =20 return 1; } diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index e82a3c4e5b44..eeab0b6e32cc 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -533,7 +533,7 @@ static void mt_get_feature(struct hid_device *hdev, str= uct hid_report *report) } =20 ret =3D hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf, - size, 0); + size, size, 0); if (ret) dev_warn(&hdev->dev, "failed to report feature\n"); } diff --git a/drivers/hid/hid-primax.c b/drivers/hid/hid-primax.c index e44d79dff8de..8db054280afb 100644 --- a/drivers/hid/hid-primax.c +++ b/drivers/hid/hid-primax.c @@ -44,7 +44,7 @@ static int px_raw_event(struct hid_device *hid, struct hi= d_report *report, data[0] |=3D (1 << (data[idx] - 0xE0)); data[idx] =3D 0; } - hid_report_raw_event(hid, HID_INPUT_REPORT, data, size, 0); + hid_report_raw_event(hid, HID_INPUT_REPORT, data, size, size, 0); return 1; =20 default: /* unknown report */ diff --git a/drivers/hid/hid-vivaldi-common.c b/drivers/hid/hid-vivaldi-com= mon.c index bf734055d4b6..b12bb5cc091a 100644 --- a/drivers/hid/hid-vivaldi-common.c +++ b/drivers/hid/hid-vivaldi-common.c @@ -85,7 +85,7 @@ void vivaldi_feature_mapping(struct hid_device *hdev, } =20 ret =3D hid_report_raw_event(hdev, HID_FEATURE_REPORT, report_data, - report_len, 0); + report_len, report_len, 0); if (ret) { dev_warn(&hdev->dev, "failed to report feature %d\n", field->report->id); diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 0d1c6d90fe21..a32320b351e3 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -90,7 +90,7 @@ static void wacom_wac_queue_flush(struct hid_device *hdev, kfree(buf); continue; } - err =3D hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, false); + err =3D hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, size, fa= lse); if (err) { hid_warn(hdev, "%s: unable to flush event due to error %d\n", __func__, err); @@ -334,7 +334,7 @@ static void wacom_feature_mapping(struct hid_device *hd= ev, data, n, WAC_CMD_RETRIES); if (ret =3D=3D n && features->type =3D=3D HID_GENERIC) { ret =3D hid_report_raw_event(hdev, - HID_FEATURE_REPORT, data, n, 0); + HID_FEATURE_REPORT, data, n, n, 0); } else if (ret =3D=3D 2 && features->type !=3D HID_GENERIC) { features->touch_max =3D data[1]; } else { @@ -395,7 +395,7 @@ static void wacom_feature_mapping(struct hid_device *hd= ev, data, n, WAC_CMD_RETRIES); if (ret =3D=3D n) { ret =3D hid_report_raw_event(hdev, HID_FEATURE_REPORT, - data, n, 0); + data, n, n, 0); } else { hid_warn(hdev, "%s: could not retrieve sensor offsets\n", __func__); diff --git a/drivers/staging/greybus/hid.c b/drivers/staging/greybus/hid.c index 1f58c907c036..f1f9f6fbc00e 100644 --- a/drivers/staging/greybus/hid.c +++ b/drivers/staging/greybus/hid.c @@ -201,7 +201,7 @@ static void gb_hid_init_report(struct gb_hid *ghid, str= uct hid_report *report) * we just need to setup the input fields, so using * hid_report_raw_event is safe. */ - hid_report_raw_event(ghid->hid, report->type, ghid->inbuf, size, 1); + hid_report_raw_event(ghid->hid, report->type, ghid->inbuf, ghid->bufsize,= size, 1); } =20 static void gb_hid_init_reports(struct gb_hid *ghid) diff --git a/include/linux/hid.h b/include/linux/hid.h index 442a80d79e89..ac432a2ef415 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -1298,8 +1298,8 @@ static inline u32 hid_report_len(struct hid_report *r= eport) return DIV_ROUND_UP(report->size, 8) + (report->id > 0); } =20 -int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type= , u8 *data, u32 size, - int interrupt); +int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type= , u8 *data, + size_t bufsize, u32 size, int interrupt); =20 /* HID quirks API */ unsigned long hid_lookup_quirk(const struct hid_device *hdev); diff --git a/include/linux/hid_bpf.h b/include/linux/hid_bpf.h index a2e47dbcf82c..19fffa4574a4 100644 --- a/include/linux/hid_bpf.h +++ b/include/linux/hid_bpf.h @@ -72,8 +72,8 @@ struct hid_ops { int (*hid_hw_output_report)(struct hid_device *hdev, __u8 *buf, size_t le= n, u64 source, bool from_bpf); int (*hid_input_report)(struct hid_device *hid, enum hid_report_type type, - u8 *data, u32 size, int interrupt, u64 source, bool from_bpf, - bool lock_already_taken); + u8 *data, size_t bufsize, u32 size, int interrupt, u64 source, + bool from_bpf, bool lock_already_taken); struct module *owner; const struct bus_type *bus_type; }; @@ -200,7 +200,8 @@ struct hid_bpf { =20 #ifdef CONFIG_HID_BPF u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, enum hid_report_= type type, u8 *data, - u32 *size, int interrupt, u64 source, bool from_bpf); + size_t *buf_size, u32 *size, int interrupt, u64 source, + bool from_bpf); int dispatch_hid_bpf_raw_requests(struct hid_device *hdev, unsigned char reportnum, __u8 *buf, u32 size, enum hid_report_type rtype, @@ -215,8 +216,11 @@ int hid_bpf_device_init(struct hid_device *hid); const u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, const u8 *rdes= c, unsigned int *size); #else /* CONFIG_HID_BPF */ static inline u8 *dispatch_hid_bpf_device_event(struct hid_device *hid, en= um hid_report_type type, - u8 *data, u32 *size, int interrupt, - u64 source, bool from_bpf) { return data; } + u8 *data, size_t *buf_size, u32 *size, + int interrupt, u64 source, bool from_bpf) +{ + return data; +} static inline int dispatch_hid_bpf_raw_requests(struct hid_device *hdev, unsigned char reportnum, u8 *buf, u32 size, enum hid_report_type rtype, --=20 2.54.0 From nobody Mon May 4 13:04:16 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3146D34AAF7; Mon, 4 May 2026 08:47:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777884471; cv=none; b=X6NaADTvozM/cX5bZ6Hg94CETTcf/h3Ovm4KhUCHdWNST6B/TMZ5ZXLkB6Hv5aBNjLLVb1VK8ojkR6Nf/oSSa98ysf4dE+9ViZytCwQFzCCzfO6y+OLNRfBlkcv/aWIcaWUu5DABfEA0ccWS1rg7TmNmw8bZ9Gpv/4cVWX/kDJ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777884471; c=relaxed/simple; bh=+JYc9gtAs3/A+XLQSsrhmAQALfOGYbOvejMYH4rLPkg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=p5ZMWbY5VY56XDhXAQNmDlSz1E1rYv838rBjXM5h+NlhqyPS3u9M5ppW2perwzc3ntWvYVWctPl8VKQmn5/8f+J8RwO8N1cwMN8zR/TSLGzmhsxkdfS46O7fY4DL9tyt4Tjza9Oh5KsyqresthEK8RbnKmlqYeujkqn4mY6WpNE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eaKa/PGR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eaKa/PGR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7CF56C2BCB9; Mon, 4 May 2026 08:47:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777884470; bh=+JYc9gtAs3/A+XLQSsrhmAQALfOGYbOvejMYH4rLPkg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=eaKa/PGR2ST0V9W04mZAyPPx4gM0d91LQZrqTTD7wNgRtXxwUgCxRKGQlvI5GgUAk gOocPiMAZWhOfff/Etdh4RG+MG7zi2XyOQbKxMUiLDRPI5bv81/AjaWhfaFG7mAetu lvV6lcsg9GY1etmIv9LmjZalmzOj79J5ta+awToZaBV1zLw8WuDaetpG34VnWnHFKT OU7NZWyHvvN7mjbbCbFWeCi90yCT9oxhTUEPikXGlSp8YHkeIG0HG6UeDK6J+9u1dR e3+v4E3cwV8j4RG1IId2RPwSD7V1abkMHJkDIltdg09CpluiV/lOrHkptRWbdr/b7s Oy+CoYGjnkFFw== From: Benjamin Tissoires Date: Mon, 04 May 2026 10:47:23 +0200 Subject: [PATCH v3 2/4] HID: core: introduce hid_safe_input_report() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-wip-fix-core-v3-2-ce1f11f4968f@kernel.org> References: <20260504-wip-fix-core-v3-0-ce1f11f4968f@kernel.org> In-Reply-To: <20260504-wip-fix-core-v3-0-ce1f11f4968f@kernel.org> To: Jiri Kosina , =?utf-8?q?Filipe_La=C3=ADns?= , Bastien Nocera , Ping Cheng , Jason Gerecke , Viresh Kumar , Johan Hovold , Alex Elder , Greg Kroah-Hartman , Lee Jones Cc: Icenowy Zheng , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, greybus-dev@lists.linaro.org, linux-staging@lists.linux.dev, linux-usb@vger.kernel.org, Benjamin Tissoires , stable@vger.kernel.org X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1777884459; l=5200; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=+JYc9gtAs3/A+XLQSsrhmAQALfOGYbOvejMYH4rLPkg=; b=LqXDLiYmsBrKX0Nt0Tc5aXHsFnZmC4CXJdjvunlrKg2EumO3TqFc+pcN4XgTKY448rJkuFhrR L/HtUZwnSQwClNpbllsVjExZ9A3B4OV6LIOBSXuJkh/sXaRbMTeYHRo X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= hid_input_report() is used in too many places to have a commit that doesn't cross subsystem borders. Instead of changing the API, introduce a new one when things matters in the transport layers: - usbhid - i2chid This effectively revert to the old behavior for those two transport layers. Fixes: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus m= emset()") Cc: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-core.c | 25 +++++++++++++++++++++++++ drivers/hid/i2c-hid/i2c-hid-core.c | 7 ++++--- drivers/hid/usbhid/hid-core.c | 11 ++++++----- include/linux/hid.h | 2 ++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index a806820df7e5..b3596851c719 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2181,6 +2181,7 @@ static int __hid_input_report(struct hid_device *hid,= enum hid_report_type type, * @interrupt: distinguish between interrupt and control transfers * * This is data entry for lower layers. + * Legacy, please use hid_safe_input_report() instead. */ int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8= *data, u32 size, int interrupt) @@ -2191,6 +2192,30 @@ int hid_input_report(struct hid_device *hid, enum hi= d_report_type type, u8 *data } EXPORT_SYMBOL_GPL(hid_input_report); =20 +/** + * hid_safe_input_report - report data from lower layer (usb, bt...) + * + * @hid: hid device + * @type: HID report type (HID_*_REPORT) + * @data: report contents + * @bufsize: allocated size of the data buffer + * @size: useful size of data parameter + * @interrupt: distinguish between interrupt and control transfers + * + * This is data entry for lower layers. + * Please use this function instead of the non safe version because we pro= vide + * here the size of the buffer, allowing hid-core to make smarter decisions + * regarding the incoming buffer. + */ +int hid_safe_input_report(struct hid_device *hid, enum hid_report_type typ= e, u8 *data, + size_t bufsize, u32 size, int interrupt) +{ + return __hid_input_report(hid, type, data, bufsize, size, interrupt, 0, + false, /* from_bpf */ + false /* lock_already_taken */); +} +EXPORT_SYMBOL_GPL(hid_safe_input_report); + bool hid_match_one_id(const struct hid_device *hdev, const struct hid_device_id *id) { diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-h= id-core.c index 5a183af3d5c6..e0a302544cef 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -574,9 +574,10 @@ static void i2c_hid_get_input(struct i2c_hid *ihid) if (ihid->hid->group !=3D HID_GROUP_RMI) pm_wakeup_event(&ihid->client->dev, 0); =20 - hid_input_report(ihid->hid, HID_INPUT_REPORT, - ihid->inbuf + sizeof(__le16), - ret_size - sizeof(__le16), 1); + hid_safe_input_report(ihid->hid, HID_INPUT_REPORT, + ihid->inbuf + sizeof(__le16), + ihid->bufsize - sizeof(__le16), + ret_size - sizeof(__le16), 1); } =20 return; diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index fbbfc0f60829..5af93b9b1fb5 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -283,9 +283,9 @@ static void hid_irq_in(struct urb *urb) break; usbhid_mark_busy(usbhid); if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) { - hid_input_report(urb->context, HID_INPUT_REPORT, - urb->transfer_buffer, - urb->actual_length, 1); + hid_safe_input_report(urb->context, HID_INPUT_REPORT, + urb->transfer_buffer, urb->transfer_buffer_length, + urb->actual_length, 1); /* * autosuspend refused while keys are pressed * because most keyboards don't wake up when @@ -482,9 +482,10 @@ static void hid_ctrl(struct urb *urb) switch (status) { case 0: /* success */ if (usbhid->ctrl[usbhid->ctrltail].dir =3D=3D USB_DIR_IN) - hid_input_report(urb->context, + hid_safe_input_report(urb->context, usbhid->ctrl[usbhid->ctrltail].report->type, - urb->transfer_buffer, urb->actual_length, 0); + urb->transfer_buffer, urb->transfer_buffer_length, + urb->actual_length, 0); break; case -ESHUTDOWN: /* unplug */ unplug =3D 1; diff --git a/include/linux/hid.h b/include/linux/hid.h index ac432a2ef415..bfb9859f391e 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -1030,6 +1030,8 @@ struct hid_field *hid_find_field(struct hid_device *h= dev, unsigned int report_ty int hid_set_field(struct hid_field *, unsigned, __s32); int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8= *data, u32 size, int interrupt); +int hid_safe_input_report(struct hid_device *hid, enum hid_report_type typ= e, u8 *data, + size_t bufsize, u32 size, int interrupt); struct hid_field *hidinput_get_led_field(struct hid_device *hid); unsigned int hidinput_count_leds(struct hid_device *hid); __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code); --=20 2.54.0 From nobody Mon May 4 13:04:16 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B48434D4FA; Mon, 4 May 2026 08:47:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777884474; cv=none; b=qdmW1X+M0QxeGLyC1dfLpwxLb52s/rzcx0y1TUQNkyaHbe7nQ2d2N4SGVlmW+57ZEmKab/lBxgqJyTsXSzE3XqXUdqBvlL35ogwNOGM86xzAGznlwMoJHytcjNJjkJ8OjgcePb1OWQHeRLouU/N71Bfk7UCO+BuMh2WVJc/FW0g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777884474; c=relaxed/simple; bh=LcCUxJZ9vDXuOX5QsjD4mqmdPrRKSI5jsjauA/s8Qsg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=chrHoISDnFU7sIwUm9GzaOA/ye1EsOCJhvFMjC319kK0+wBgelm1k5fvWUjiZh5cmY7trTNNd7pfUq3Mup7suAlUys0u/W6rtQUguagsfrDkXY0CK03+nPyUYjgHfC/ivWDl0vtaYdF2IYlGxwuUKr2eJ/BhiBtmXummaMzPWH0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oJEbFzGO; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oJEbFzGO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 303D5C2BCF4; Mon, 4 May 2026 08:47:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777884474; bh=LcCUxJZ9vDXuOX5QsjD4mqmdPrRKSI5jsjauA/s8Qsg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=oJEbFzGO/HeaDcyQfs9EYHpLd5MGXMATak+RRUXiV3D5Qx9mkVGrRjQBqbW1YkIV6 quXO9WD9nbWEb3BTD1Cnmabm1ar9pSOmNNebiSo1C+VlBR9ilEpOzVA07hVJHu1WHs xLM9LlIhS5LhYGl08iGbeOAWFi/6ANvF+B7jS6IJlIpjNyAdpmIy49ZJsxlXTK/dPd FQUzug4JkKk/d7Hvx4s0ZmCOurDxeo9/gAOgWoNAl8oeN5c6uID2eLzbv+aiSi94Vr 03ZxNgdgosMVptmq7fhufGFzkriFkkVf1zdIbduNsvt42LDvTtzaOCSO0ch/UDthCv nHZUtztBz2k7w== From: Benjamin Tissoires Date: Mon, 04 May 2026 10:47:24 +0200 Subject: [PATCH v3 3/4] HID: multitouch: use __free(kfree) to clean up temporary buffers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-wip-fix-core-v3-3-ce1f11f4968f@kernel.org> References: <20260504-wip-fix-core-v3-0-ce1f11f4968f@kernel.org> In-Reply-To: <20260504-wip-fix-core-v3-0-ce1f11f4968f@kernel.org> To: Jiri Kosina , =?utf-8?q?Filipe_La=C3=ADns?= , Bastien Nocera , Ping Cheng , Jason Gerecke , Viresh Kumar , Johan Hovold , Alex Elder , Greg Kroah-Hartman , Lee Jones Cc: Icenowy Zheng , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, greybus-dev@lists.linaro.org, linux-staging@lists.linux.dev, linux-usb@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1777884459; l=2586; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=LcCUxJZ9vDXuOX5QsjD4mqmdPrRKSI5jsjauA/s8Qsg=; b=BR42A1lrnPuRPFKsvC0KYNwOErDyVZ7Eg+qiAzaOplp9OLE8nEWArXfGLIfCFj0HRRhHH7wU6 2axtBUqFVXwAtDuLY1US0Lrl/AdYYD5GL1txUO2cXLdZ7luUy7bfM2Y X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= This simplifies error handling and protects against memory leaks. Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-multitouch.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index eeab0b6e32cc..b19463e545d6 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -507,7 +507,6 @@ static void mt_get_feature(struct hid_device *hdev, str= uct hid_report *report) { int ret; u32 size =3D hid_report_len(report); - u8 *buf; =20 /* * Do not fetch the feature report if the device has been explicitly @@ -516,7 +515,7 @@ static void mt_get_feature(struct hid_device *hdev, str= uct hid_report *report) if (hdev->quirks & HID_QUIRK_NO_INIT_REPORTS) return; =20 - buf =3D hid_alloc_report_buf(report, GFP_KERNEL); + u8 *buf __free(kfree) =3D hid_alloc_report_buf(report, GFP_KERNEL); if (!buf) return; =20 @@ -529,7 +528,7 @@ static void mt_get_feature(struct hid_device *hdev, str= uct hid_report *report) /* The report ID in the request and the response should match */ if (report->id !=3D buf[0]) { hid_err(hdev, "Returned feature report did not match the request\n"); - goto free; + return; } =20 ret =3D hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf, @@ -537,9 +536,6 @@ static void mt_get_feature(struct hid_device *hdev, str= uct hid_report *report) if (ret) dev_warn(&hdev->dev, "failed to report feature\n"); } - -free: - kfree(buf); } =20 static void mt_feature_mapping(struct hid_device *hdev, @@ -1658,7 +1654,6 @@ static bool mt_need_to_apply_feature(struct hid_devic= e *hdev, struct mt_class *cls =3D &td->mtclass; struct hid_report *report =3D field->report; unsigned int index =3D usage->usage_index; - char *buf; u32 report_len; int max; =20 @@ -1673,17 +1668,18 @@ static bool mt_need_to_apply_feature(struct hid_dev= ice *hdev, return false; =20 if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) { - report_len =3D hid_report_len(report); - buf =3D hid_alloc_report_buf(report, GFP_KERNEL); + char *buf __free(kfree) =3D hid_alloc_report_buf(report, GFP_KERNEL); + if (!buf) { hid_err(hdev, "failed to allocate buffer for report\n"); return false; } + + report_len =3D hid_report_len(report); hid_hw_raw_request(hdev, report->id, buf, report_len, HID_FEATURE_REPORT, HID_REQ_GET_REPORT); - kfree(buf); } =20 field->value[index] =3D td->inputmode_value; --=20 2.54.0 From nobody Mon May 4 13:04:16 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0CEDD3451A9; Mon, 4 May 2026 08:47:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777884478; cv=none; b=SU18tYhh9+n+AgyjnPYhsQ2NIdCiocf1QtDrOQxiXEnVuPZsz2IQqek4E2PLGuSXpPZhqYi/v9+olI/9CpV6WNf+0q2sOew8SlAVpKXY6fbX46bCU5OYcnuInKYoH8pMKYxfazWD1/49YTyVMOewjZuff1LfEqrCq8nb465R7AM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777884478; c=relaxed/simple; bh=DXYQc7X2AK50Mj+CIjz8BuE9j6+b2UJfrn8B83jW6pg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XFVhJAymrPo4wNBdAQbf3LwD18zQQQ9wx9p/KVKuZYbXD3RjP6QujwOiiWpjSES8eNJzvz1ptXdsVg+ymy4pY8n73+e7kDXcMHkAOY1sLUN2WMckfIUN2pu/5aohJSIley4wJwhownNERYZ1ROGGkPbjdU0Psaz3LsZneYi9f9I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=l0k/1KUb; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="l0k/1KUb" Received: by smtp.kernel.org (Postfix) with ESMTPSA id ACE76C2BCB8; Mon, 4 May 2026 08:47:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777884477; bh=DXYQc7X2AK50Mj+CIjz8BuE9j6+b2UJfrn8B83jW6pg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=l0k/1KUb6RG000H+kGDm7nhsCb421I1oUGeBEVA+tFHRcxDrBra82APpHH3RV2G0Y EiVgMMfdALzdSpak9bXChuaY/6RXE3Chp1R3o7YoIC1fTW0k6ILvk6ylV1lAhMv8u6 F6UiOz+aYqrlmRC1f5TuMnV+orj3cOj/XEcrOI5nx77b2HE9/k0dwwQJQk2pmrhHNu 2+djzl8+4/G8g400OzvpzQSSZuSsMN+/vGtrMkn8cJKnIiY8uJbpzAJevOJoY5ckng QT9ZmSI9/9G4KloPow6DnBZuuk73oQafeSaARVXCzq6lUhhQ9It0DM2gScUIeyRHNw UvqL2OH9CeLWQ== From: Benjamin Tissoires Date: Mon, 04 May 2026 10:47:25 +0200 Subject: [PATCH v3 4/4] HID: wacom: use __free(kfree) to clean up temporary buffers Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260504-wip-fix-core-v3-4-ce1f11f4968f@kernel.org> References: <20260504-wip-fix-core-v3-0-ce1f11f4968f@kernel.org> In-Reply-To: <20260504-wip-fix-core-v3-0-ce1f11f4968f@kernel.org> To: Jiri Kosina , =?utf-8?q?Filipe_La=C3=ADns?= , Bastien Nocera , Ping Cheng , Jason Gerecke , Viresh Kumar , Johan Hovold , Alex Elder , Greg Kroah-Hartman , Lee Jones Cc: Icenowy Zheng , linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, greybus-dev@lists.linaro.org, linux-staging@lists.linux.dev, linux-usb@vger.kernel.org, Benjamin Tissoires X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1777884459; l=6985; i=bentiss@kernel.org; s=20230215; h=from:subject:message-id; bh=DXYQc7X2AK50Mj+CIjz8BuE9j6+b2UJfrn8B83jW6pg=; b=JZtCh8p6BoKS4cb3iSfsODBVljPa+P4bPc7keNXAL6OSxZWucSnYuEXncjjidOV597oQrMP5j fHh9FhOC4hwCZepPA65Bg3GJsT7OykiU+xZ1GavX8XeXU2p3Ha02Zmw X-Developer-Key: i=bentiss@kernel.org; a=ed25519; pk=7D1DyAVh6ajCkuUTudt/chMuXWIJHlv2qCsRkIizvFw= This simplifies error handling and protects against memory leaks. Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-core.c | 4 ++-- drivers/hid/wacom_sys.c | 40 +++++++++++++--------------------------- 2 files changed, 15 insertions(+), 29 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b3596851c719..7fc20e0405ad 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2050,8 +2050,8 @@ int hid_report_raw_event(struct hid_device *hid, enum= hid_report_type type, u8 * return 0; =20 if (unlikely(bsize < csize)) { - hid_warn_ratelimited(hid, "Event data for report %d is incorrect (%d vs = %ld)\n", - report->id, csize, bsize); + hid_warn_ratelimited(hid, "Event data for report %d is incorrect (%d vs = %d)\n", + report->id, csize, (unsigned int)bsize); return -EINVAL; } =20 diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index a32320b351e3..adb31f54e524 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -70,11 +70,10 @@ static void wacom_wac_queue_flush(struct hid_device *hd= ev, { while (!kfifo_is_empty(fifo)) { int size =3D kfifo_peek_len(fifo); - u8 *buf; unsigned int count; int err; =20 - buf =3D kzalloc(size, GFP_KERNEL); + u8 *buf __free(kfree) =3D kzalloc(size, GFP_KERNEL); if (!buf) { kfifo_skip(fifo); continue; @@ -87,7 +86,6 @@ static void wacom_wac_queue_flush(struct hid_device *hdev, // to flush seems reasonable enough, however. hid_warn(hdev, "%s: removed fifo entry with unexpected size\n", __func__); - kfree(buf); continue; } err =3D hid_report_raw_event(hdev, HID_INPUT_REPORT, buf, size, size, fa= lse); @@ -95,8 +93,6 @@ static void wacom_wac_queue_flush(struct hid_device *hdev, hid_warn(hdev, "%s: unable to flush event due to error %d\n", __func__, err); } - - kfree(buf); } } =20 @@ -311,7 +307,6 @@ static void wacom_feature_mapping(struct hid_device *hd= ev, struct wacom_features *features =3D &wacom->wacom_wac.features; struct hid_data *hid_data =3D &wacom->wacom_wac.hid_data; unsigned int equivalent_usage =3D wacom_equivalent_usage(usage->hid); - u8 *data; int ret; u32 n; =20 @@ -325,10 +320,11 @@ static void wacom_feature_mapping(struct hid_device *= hdev, /* leave touch_max as is if predefined */ if (!features->touch_max) { /* read manually */ - n =3D hid_report_len(field->report); - data =3D hid_alloc_report_buf(field->report, GFP_KERNEL); + u8 *data __free(kfree) =3D hid_alloc_report_buf(field->report, GFP_KERN= EL); + if (!data) break; + n =3D hid_report_len(field->report); data[0] =3D field->report->id; ret =3D wacom_get_report(hdev, HID_FEATURE_REPORT, data, n, WAC_CMD_RETRIES); @@ -344,7 +340,6 @@ static void wacom_feature_mapping(struct hid_device *hd= ev, "defaulting to %d\n", features->touch_max); } - kfree(data); } break; case HID_DG_INPUTMODE: @@ -386,10 +381,11 @@ static void wacom_feature_mapping(struct hid_device *= hdev, case WACOM_HID_WD_OFFSETRIGHT: case WACOM_HID_WD_OFFSETBOTTOM: /* read manually */ - n =3D hid_report_len(field->report); - data =3D hid_alloc_report_buf(field->report, GFP_KERNEL); + u8 *data __free(kfree) =3D hid_alloc_report_buf(field->report, GFP_KERNE= L); + if (!data) break; + n =3D hid_report_len(field->report); data[0] =3D field->report->id; ret =3D wacom_get_report(hdev, HID_FEATURE_REPORT, data, n, WAC_CMD_RETRIES); @@ -400,7 +396,6 @@ static void wacom_feature_mapping(struct hid_device *hd= ev, hid_warn(hdev, "%s: could not retrieve sensor offsets\n", __func__); } - kfree(data); break; } } @@ -581,7 +576,6 @@ static int wacom_hid_set_device_mode(struct hid_device = *hdev) static int wacom_set_device_mode(struct hid_device *hdev, struct wacom_wac *wacom_wac) { - u8 *rep_data; struct hid_report *r; struct hid_report_enum *re; u32 length; @@ -595,7 +589,7 @@ static int wacom_set_device_mode(struct hid_device *hde= v, if (!r) return -EINVAL; =20 - rep_data =3D hid_alloc_report_buf(r, GFP_KERNEL); + u8 *rep_data __free(kfree) =3D hid_alloc_report_buf(r, GFP_KERNEL); if (!rep_data) return -ENOMEM; =20 @@ -614,8 +608,6 @@ static int wacom_set_device_mode(struct hid_device *hde= v, rep_data[1] !=3D wacom_wac->mode_report && limit++ < WAC_MSG_RETRIES); =20 - kfree(rep_data); - return error < 0 ? error : 0; } =20 @@ -921,7 +913,6 @@ static int wacom_add_shared_data(struct hid_device *hde= v) =20 static int wacom_led_control(struct wacom *wacom) { - unsigned char *buf; int retval; unsigned char report_id =3D WAC_CMD_LED_CONTROL; int buf_size =3D 9; @@ -940,7 +931,8 @@ static int wacom_led_control(struct wacom *wacom) report_id =3D WAC_CMD_WL_INTUOSP2; buf_size =3D 51; } - buf =3D kzalloc(buf_size, GFP_KERNEL); + + unsigned char *buf __free(kfree) =3D kzalloc(buf_size, GFP_KERNEL); if (!buf) return -ENOMEM; =20 @@ -996,7 +988,6 @@ static int wacom_led_control(struct wacom *wacom) =20 retval =3D wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, buf, buf_siz= e, WAC_CMD_RETRIES); - kfree(buf); =20 return retval; } @@ -1004,11 +995,10 @@ static int wacom_led_control(struct wacom *wacom) static int wacom_led_putimage(struct wacom *wacom, int button_id, u8 xfer_= id, const unsigned len, const void *img) { - unsigned char *buf; int i, retval; const unsigned chunk_len =3D len / 4; /* 4 chunks are needed to be sent */ =20 - buf =3D kzalloc(chunk_len + 3 , GFP_KERNEL); + unsigned char *buf __free(kfree) =3D kzalloc(chunk_len + 3, GFP_KERNEL); if (!buf) return -ENOMEM; =20 @@ -1018,7 +1008,7 @@ static int wacom_led_putimage(struct wacom *wacom, in= t button_id, u8 xfer_id, retval =3D wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, buf, 2, WAC_CMD_RETRIES); if (retval < 0) - goto out; + return retval; =20 buf[0] =3D xfer_id; buf[1] =3D button_id & 0x07; @@ -1038,8 +1028,6 @@ static int wacom_led_putimage(struct wacom *wacom, in= t button_id, u8 xfer_id, wacom_set_report(wacom->hdev, HID_FEATURE_REPORT, buf, 2, WAC_CMD_RETRIES); =20 -out: - kfree(buf); return retval; } =20 @@ -1948,10 +1936,9 @@ static int wacom_remote_create_attr_group(struct wac= om *wacom, __u32 serial, static int wacom_cmd_unpair_remote(struct wacom *wacom, unsigned char sele= ctor) { const size_t buf_size =3D 2; - unsigned char *buf; int retval; =20 - buf =3D kzalloc(buf_size, GFP_KERNEL); + unsigned char *buf __free(kfree) =3D kzalloc(buf_size, GFP_KERNEL); if (!buf) return -ENOMEM; =20 @@ -1960,7 +1947,6 @@ static int wacom_cmd_unpair_remote(struct wacom *waco= m, unsigned char selector) =20 retval =3D wacom_set_report(wacom->hdev, HID_OUTPUT_REPORT, buf, buf_size, WAC_CMD_RETRIES); - kfree(buf); =20 return retval; } --=20 2.54.0