Skip to content

Commit 258d500

Browse files
jfischer-noMarekPieta
authored andcommitted
[nrf fromtree] usb: device_next: hid: fix Get Report buffer handling
After the get_report() callback, we need to determine how many bytes the HID device wrote to the report buffer. Use the callback return value to do this, and modify the net_buf data length value if get_report was successful. Reported-by: Marek Pieta <[email protected]> Signed-off-by: Johann Fischer <[email protected]> (cherry picked from commit af63e48)
1 parent 18285a0 commit 258d500

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

include/zephyr/usb/class/usbd_hid.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,10 @@ struct hid_device_ops {
106106
* feature, input, or output report, which is specified by the argument
107107
* type. If there is no report ID in the report descriptor, the id
108108
* argument is zero. The callback implementation must check the
109-
* arguments, such as whether the report type is supported, and return
110-
* a nonzero value to indicate an unsupported type or an error.
109+
* arguments, such as whether the report type is supported and the
110+
* report length, and return a negative value to indicate an
111+
* unsupported type or an error, or return the length of the report
112+
* written to the buffer.
111113
*/
112114
int (*get_report)(const struct device *dev,
113115
const uint8_t type, const uint8_t id,

subsys/usb/device_next/class/usbd_hid.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,25 +231,34 @@ static int handle_get_report(const struct device *dev,
231231
const uint8_t id = HID_GET_REPORT_ID(setup->wValue);
232232
struct hid_device_data *const ddata = dev->data;
233233
const struct hid_device_ops *ops = ddata->ops;
234+
const size_t size = net_buf_tailroom(buf);
235+
int ret = 0;
234236

235237
switch (type) {
236238
case HID_REPORT_TYPE_INPUT:
237239
LOG_DBG("Get Report, Input Report ID %u", id);
238-
errno = ops->get_report(dev, type, id, net_buf_tailroom(buf), buf->data);
240+
ret = ops->get_report(dev, type, id, size, buf->data);
239241
break;
240242
case HID_REPORT_TYPE_OUTPUT:
241243
LOG_DBG("Get Report, Output Report ID %u", id);
242-
errno = ops->get_report(dev, type, id, net_buf_tailroom(buf), buf->data);
244+
ret = ops->get_report(dev, type, id, size, buf->data);
243245
break;
244246
case HID_REPORT_TYPE_FEATURE:
245247
LOG_DBG("Get Report, Feature Report ID %u", id);
246-
errno = ops->get_report(dev, type, id, net_buf_tailroom(buf), buf->data);
248+
ret = ops->get_report(dev, type, id, size, buf->data);
247249
break;
248250
default:
249251
errno = -ENOTSUP;
250252
break;
251253
}
252254

255+
if (ret > 0) {
256+
__ASSERT(ret <= size, "Buffer overflow in the HID driver");
257+
net_buf_add(buf, MIN(size, ret));
258+
} else {
259+
errno = ret ? ret : -ENOTSUP;
260+
}
261+
253262
return 0;
254263
}
255264

0 commit comments

Comments
 (0)