From 0b5d86b38ae9aec92ef96b9227a404a2df3c9234 Mon Sep 17 00:00:00 2001 From: Matthew Nygard Dodd Date: Mon, 18 Nov 2024 07:15:01 +0300 Subject: [PATCH 1/2] uhid(4): update ugd_actlen in USB_GET_REPORT ioctl USB_GET_REPORT ioctl is documented to update ugd_actlen on return with the number of bytes copied. It does not do this. Reviewed by: wulf PR: 282790 MFC after: 1 week --- sys/dev/usb/input/uhid.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c index 863e04f4e52b..098ec4364df7 100644 --- a/sys/dev/usb/input/uhid.c +++ b/sys/dev/usb/input/uhid.c @@ -633,11 +633,13 @@ uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, default: return (EINVAL); } + size = imin(ugd->ugd_maxlen, size); if (id != 0) error = copyin(ugd->ugd_data, &id, 1); if (error == 0) error = uhid_get_report(sc, ugd->ugd_report_type, id, - NULL, ugd->ugd_data, imin(ugd->ugd_maxlen, size)); + NULL, ugd->ugd_data, size); + ugd->ugd_actlen = size; break; case USB_SET_REPORT: From f4f46a2eef3be6d19c65a4ca4ee70f365dd5be4f Mon Sep 17 00:00:00 2001 From: Matthew Nygard Dodd Date: Mon, 18 Nov 2024 07:25:10 +0300 Subject: [PATCH 2/2] hidraw(4): update hgd_actlen in HIDRAW_GET_REPORT ioctl HIDRAW_GET_REPORT ioctl is documented to update hgd_actlen on return with the number of bytes copied. It does not do this. Reviewed by: wulf PR: 282790 MFC after: 1 week --- sys/dev/hid/hidraw.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sys/dev/hid/hidraw.c b/sys/dev/hid/hidraw.c index 6a05b633cfc8..ccfdcdddf545 100644 --- a/sys/dev/hid/hidraw.c +++ b/sys/dev/hid/hidraw.c @@ -570,6 +570,7 @@ hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct hidraw_devinfo *hd; const char *devname; uint32_t size; + hid_size_t actsize; int id, len; int error = 0; @@ -747,16 +748,16 @@ hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, } size = MIN(hgd->hgd_maxlen, size); buf = HIDRAW_LOCAL_ALLOC(local_buf, size); - error = hid_get_report(sc->sc_dev, buf, size, NULL, + actsize = 0; + error = hid_get_report(sc->sc_dev, buf, size, &actsize, hgd->hgd_report_type, id); if (!error) - error = copyout(buf, hgd->hgd_data, size); + error = copyout(buf, hgd->hgd_data, actsize); HIDRAW_LOCAL_FREE(local_buf, buf); + hgd->hgd_actlen = actsize; #ifdef COMPAT_FREEBSD32 - /* - * HIDRAW_GET_REPORT is declared _IOWR, but hgd is not written - * so we don't call update_hgd32(). - */ + if (hgd32 != NULL) + update_hgd32(hgd, hgd32); #endif return (error);