Skip to content

Commit 8614c04

Browse files
mjbommargregkh
authored andcommitted
HID: hyperv: validate initial device info bounds
commit 934b777 upstream. The Hyper-V synthetic HID host supplies SYNTH_HID_INITIAL_DEVICE_INFO messages that contain a HID descriptor followed by the report descriptor bytes. mousevsc_on_receive_device_info() trusts bLength and wDescriptorLength without checking that the received packet contains both byte ranges. A malformed host or backend message can therefore make the guest read past the received VMBus packet while copying the report descriptor. Pass the received initial-device-info size into the parser and reject descriptor lengths that exceed the packet. Impact: A malicious Hyper-V host or backend can crash a guest by sending a short initial device-info message with an oversized HID report descriptor length. Fixes: b95f5bc ("HID: Move the hid-hyperv driver out of staging") Cc: stable@vger.kernel.org Assisted-by: Codex:gpt-5-5-xhigh Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent d37ff4e commit 8614c04

1 file changed

Lines changed: 24 additions & 3 deletions

File tree

drivers/hid/hid-hyperv.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,18 +179,32 @@ static void mousevsc_free_device(struct mousevsc_dev *device)
179179
}
180180

181181
static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
182-
struct synthhid_device_info *device_info)
182+
struct synthhid_device_info *device_info,
183+
u32 device_info_size)
183184
{
184185
int ret = 0;
185186
struct hid_descriptor *desc;
186187
struct mousevsc_prt_msg ack;
188+
size_t desc_offset;
189+
size_t desc_size;
187190

188191
input_device->dev_info_status = -ENOMEM;
189192

193+
if (device_info_size < sizeof(*device_info)) {
194+
input_device->dev_info_status = -EINVAL;
195+
goto cleanup;
196+
}
197+
190198
input_device->hid_dev_info = device_info->hid_dev_info;
191199
desc = &device_info->hid_descriptor;
200+
desc_offset = offsetof(struct synthhid_device_info, hid_descriptor);
201+
desc_size = device_info_size - desc_offset;
192202
if (desc->bLength == 0)
193203
goto cleanup;
204+
if (desc->bLength < sizeof(*desc) || desc->bLength > desc_size) {
205+
input_device->dev_info_status = -EINVAL;
206+
goto cleanup;
207+
}
194208

195209
/* The pointer is not NULL when we resume from hibernation */
196210
kfree(input_device->hid_desc);
@@ -205,6 +219,10 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
205219
input_device->dev_info_status = -EINVAL;
206220
goto cleanup;
207221
}
222+
if (input_device->report_desc_size > desc_size - desc->bLength) {
223+
input_device->dev_info_status = -EINVAL;
224+
goto cleanup;
225+
}
208226

209227
/* The pointer is not NULL when we resume from hibernation */
210228
kfree(input_device->report_desc);
@@ -285,14 +303,17 @@ static void mousevsc_on_receive(struct hv_device *device,
285303
break;
286304

287305
case SYNTH_HID_INITIAL_DEVICE_INFO:
288-
WARN_ON(pipe_msg->size < sizeof(struct hv_input_dev_info));
306+
if (WARN_ON_ONCE(pipe_msg->size <
307+
sizeof(struct synthhid_device_info)))
308+
break;
289309

290310
/*
291311
* Parse out the device info into device attr,
292312
* hid desc and report desc
293313
*/
294314
mousevsc_on_receive_device_info(input_dev,
295-
(struct synthhid_device_info *)pipe_msg->data);
315+
(struct synthhid_device_info *)pipe_msg->data,
316+
pipe_msg->size);
296317
break;
297318
case SYNTH_HID_INPUT_REPORT:
298319
input_report =

0 commit comments

Comments
 (0)