[PATCH] HID: hyperv: make pointer arithmetics understandable for FORTIFY_SOURCE

Jiri Kosina <[email protected]>
Newsgroups gmane.linux.kernel
Message-ID <[email protected]>
From: Jiri Kosina <[email protected]>

Commit 83df7b5fa6735b5084ecd2 ("HID: hyperv: add KUnit coverage for device info
bounds") introduced this piece of code

	report = ((u8 *)&info->hid_descriptor) + info->hid_descriptor.bLength;
	memset(report, 0x42, 4);

to populate the report descriptor, making use of the fact that the report.
&info->hid_descriptor points to a struct hid_descriptor (which is a fixed-size struct)
GCC's FORTIFY_SOURCE infer the object size from that specific struct field rather than the
outer dynamically allocated info buffer. As a result, writing past sizeof(struct hid_descriptor)
triggers the __write_overflow_field warning.

Calculate the pointer offset using info directly, so the compiler evaluates the
memory bounds against the allocated flexible layout of struct
synthhid_device_info instead of the nested struct.

Fixes: 83df7b5fa6735b5084ecd2 ("HID: hyperv: add KUnit coverage for device info bounds")
Reported-by: Jürgen Groß <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
---
 drivers/hid/hid-hyperv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
index 6579bd19da13..4a10b24da9fa 100644
--- a/drivers/hid/hid-hyperv.c
+++ b/drivers/hid/hid-hyperv.c
@@ -687,7 +687,7 @@ static void mousevsc_device_info_valid_descriptor(struct kunit *test)
 
 	info->hid_descriptor.bLength = sizeof(struct hid_descriptor);
 	info->hid_descriptor.rpt_desc.wDescriptorLength = cpu_to_le16(4);
-	report = ((u8 *)&info->hid_descriptor) + info->hid_descriptor.bLength;
+	report = (u8 *)info + offsetof(struct synthhid_device_info, hid_descriptor) + info->hid_descriptor.bLength;
 	memset(report, 0x42, 4);
 
 	mousevsc_on_receive_device_info(input_dev, info, sizeof(*info) + 4);
@@ -713,7 +713,7 @@ static void mousevsc_device_info_report_desc_oob(struct kunit *test)
 
 	info->hid_descriptor.bLength = sizeof(struct hid_descriptor);
 	info->hid_descriptor.rpt_desc.wDescriptorLength = cpu_to_le16(64);
-	report = ((u8 *)&info->hid_descriptor) + info->hid_descriptor.bLength;
+	report = (u8 *)info + offsetof(struct synthhid_device_info, hid_descriptor) + info->hid_descriptor.bLength;
 	memset(report, 0x42, 8);
 
 	mousevsc_on_receive_device_info(input_dev, info, sizeof(*info) + 8);

-- 
Jiri Kosina
SUSE Labs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.