diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-05-29 08:51:46 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-05-29 08:51:46 -0700 |
| commit | e6f4f084ecd876a333c4cf13d0229217dbfcd8e8 (patch) | |
| tree | 1562d2b608fe4d11aaaaa10d13db2bcdda1ca8c8 /drivers | |
| parent | 8fde5d1d47f69db6082dfa34500c27f8485389a5 (diff) | |
| parent | c0a8899e02ddebd51e2589835182c239c2e224ae (diff) | |
Merge tag 'hid-for-linus-2026052801' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID fixes from Benjamin Tissoires:
- buffer overflow fix for lenovo (Kean) and wacom (Lee Jones) drivers
- segfaults prevention in lenovo-go driver when used with an emulated
device (Louis Clinckx)
- cleanup of resources in u2fzero (Myeonghun Pak)
- a quirk for a USB mouse and a cleanup in hid.h (hlleng and Liu Kai)
* tag 'hid-for-linus-2026052801' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
HID: wacom: Fix OOB write in wacom_hid_set_device_mode()
HID: lenovo-go: drop dead NULL check on to_usb_interface()
HID: lenovo-go: reject non-USB transports in probe
HID: lenovo: Fix buffer over-read and unaligned access in X12 Tab raw_event handler
HID: quirks: Add ALWAYS_POLL quirk for SIGMACHIP USB mouse
HID: remove duplicate hid_warn_ratelimited definition
HID: u2fzero: free allocated URB on probe errors
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/hid/hid-ids.h | 1 | ||||
| -rw-r--r-- | drivers/hid/hid-lenovo-go-s.c | 11 | ||||
| -rw-r--r-- | drivers/hid/hid-lenovo-go.c | 6 | ||||
| -rw-r--r-- | drivers/hid/hid-lenovo.c | 5 | ||||
| -rw-r--r-- | drivers/hid/hid-quirks.c | 1 | ||||
| -rw-r--r-- | drivers/hid/hid-u2fzero.c | 22 | ||||
| -rw-r--r-- | drivers/hid/wacom_sys.c | 13 | ||||
| -rw-r--r-- | drivers/hid/wacom_wac.h | 1 |
8 files changed, 38 insertions, 22 deletions
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 4657d96fb083..426ff78c1c03 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -1284,6 +1284,7 @@ #define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f #define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002 +#define USB_DEVICE_ID_SIGMA_MICRO_USB_MOUSE 0x0034 #define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD2 0x0059 #define USB_VENDOR_ID_SIGMATEL 0x066F diff --git a/drivers/hid/hid-lenovo-go-s.c b/drivers/hid/hid-lenovo-go-s.c index ff1782a75191..a72f7f748cb5 100644 --- a/drivers/hid/hid-lenovo-go-s.c +++ b/drivers/hid/hid-lenovo-go-s.c @@ -382,11 +382,9 @@ static int get_endpoint_address(struct hid_device *hdev) struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct usb_host_endpoint *ep; - if (intf) { - ep = intf->cur_altsetting->endpoint; - if (ep) - return ep->desc.bEndpointAddress; - } + ep = intf->cur_altsetting->endpoint; + if (ep) + return ep->desc.bEndpointAddress; return -ENODEV; } @@ -1461,6 +1459,9 @@ static int hid_gos_probe(struct hid_device *hdev, { int ret, ep; + if (!hid_is_usb(hdev)) + return -EINVAL; + ret = hid_parse(hdev); if (ret) { hid_err(hdev, "Parse failed\n"); diff --git a/drivers/hid/hid-lenovo-go.c b/drivers/hid/hid-lenovo-go.c index d4d26c783356..e0c9d5ec9451 100644 --- a/drivers/hid/hid-lenovo-go.c +++ b/drivers/hid/hid-lenovo-go.c @@ -641,9 +641,6 @@ static int get_endpoint_address(struct hid_device *hdev) struct usb_interface *intf = to_usb_interface(hdev->dev.parent); struct usb_host_endpoint *ep; - if (!intf) - return -ENODEV; - ep = intf->cur_altsetting->endpoint; if (!ep) return -ENODEV; @@ -2419,6 +2416,9 @@ static int hid_go_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret, ep; + if (!hid_is_usb(hdev)) + return -EINVAL; + hdev->quirks |= HID_QUIRK_INPUT_PER_APP | HID_QUIRK_MULTI_INPUT; ret = hid_parse(hdev); diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index a6b73e03c16b..c11957ae8b77 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -30,6 +30,7 @@ #include <linux/hid.h> #include <linux/input.h> #include <linux/leds.h> +#include <linux/unaligned.h> #include <linux/workqueue.h> #include "hid-ids.h" @@ -793,8 +794,8 @@ static int lenovo_raw_event(struct hid_device *hdev, */ if (unlikely((hdev->product == USB_DEVICE_ID_LENOVO_X12_TAB || hdev->product == USB_DEVICE_ID_LENOVO_X12_TAB2) - && size >= 3 && report->id == 0x03)) - return lenovo_raw_event_TP_X12_tab(hdev, le32_to_cpu(*(__le32 *)data)); + && size >= 4 && report->id == 0x03)) + return lenovo_raw_event_TP_X12_tab(hdev, get_unaligned_le32(data)); return 0; } diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 512049963978..57d8efdd9b89 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -187,6 +187,7 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD), HID_QUIRK_NO_INIT_REPORTS }, + { HID_USB_DEVICE(USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_USB_MOUSE), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS1030_TOUCH), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS817_TOUCH), HID_QUIRK_NOGET }, diff --git a/drivers/hid/hid-u2fzero.c b/drivers/hid/hid-u2fzero.c index 744a91e6e78c..82404b6e2d25 100644 --- a/drivers/hid/hid-u2fzero.c +++ b/drivers/hid/hid-u2fzero.c @@ -341,29 +341,33 @@ static int u2fzero_probe(struct hid_device *hdev, if (ret) return ret; - u2fzero_fill_in_urb(dev); + ret = u2fzero_fill_in_urb(dev); + if (ret) + goto err_hid_hw_stop; dev->present = true; minor = ((struct hidraw *) hdev->hidraw)->minor; ret = u2fzero_init_led(dev, minor); - if (ret) { - hid_hw_stop(hdev); - return ret; - } + if (ret) + goto err_free_urb; hid_info(hdev, "%s LED initialised\n", hw_configs[dev->hw_revision].name); ret = u2fzero_init_hwrng(dev, minor); - if (ret) { - hid_hw_stop(hdev); - return ret; - } + if (ret) + goto err_free_urb; hid_info(hdev, "%s RNG initialised\n", hw_configs[dev->hw_revision].name); return 0; + +err_free_urb: + usb_free_urb(dev->urb); +err_hid_hw_stop: + hid_hw_stop(hdev); + return ret; } static void u2fzero_remove(struct hid_device *hdev) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index a32320b351e3..2220168bf116 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -356,6 +356,7 @@ static void wacom_feature_mapping(struct hid_device *hdev, hid_data->inputmode = field->report->id; hid_data->inputmode_index = usage->usage_index; + hid_data->inputmode_field_index = field->index; break; case HID_UP_DIGITIZER: @@ -571,9 +572,14 @@ static int wacom_hid_set_device_mode(struct hid_device *hdev) re = &(hdev->report_enum[HID_FEATURE_REPORT]); r = re->report_id_hash[hid_data->inputmode]; - if (r) { - r->field[0]->value[hid_data->inputmode_index] = 2; - hid_hw_request(hdev, r, HID_REQ_SET_REPORT); + if (r && hid_data->inputmode_field_index >= 0 && + hid_data->inputmode_field_index < r->maxfield) { + struct hid_field *field = r->field[hid_data->inputmode_field_index]; + + if (field && hid_data->inputmode_index < field->report_count) { + field->value[hid_data->inputmode_index] = 2; + hid_hw_request(hdev, r, HID_REQ_SET_REPORT); + } } return 0; } @@ -2846,6 +2852,7 @@ static int wacom_probe(struct hid_device *hdev, return -ENODEV; wacom_wac->hid_data.inputmode = -1; + wacom_wac->hid_data.inputmode_field_index = -1; wacom_wac->mode_report = -1; if (hid_is_usb(hdev)) { diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index d4f7d8ca1e7e..126bec6e5c0c 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -295,6 +295,7 @@ struct wacom_shared { struct hid_data { __s16 inputmode; /* InputMode HID feature, -1 if non-existent */ __s16 inputmode_index; /* InputMode HID feature index in the report */ + __s16 inputmode_field_index; /* InputMode HID feature field index in the report */ bool sense_state; bool inrange_state; bool eraser; |
