Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid

Pull HID fixes from Jiri Kosina:

- fixes for a couple potential memory corruption problems (the HW would
have to be manufactured to be deliberately evil to trigger those)
found by Ben Hawkes
- fix for potential infinite loop when using sysfs interface of
logitech driver, from Simon Wood
- a couple more simple driver fixes

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
HID: fix a couple of off-by-ones
HID: logitech: perform bounds checking on device_id early enough
HID: logitech: fix bounds checking on LED report size
HID: logitech: Prevent possibility of infinite loop when using /sys interface
HID: rmi: print an error if F11 is not found instead of stopping the device
HID: hid-sensor-hub: use devm_ functions consistently
HID: huion: Use allocated buffer for DMA
HID: huion: Fail on parameter retrieval errors

+115 -94
+1 -1
drivers/hid/hid-cherry.c
··· 28 28 static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, 29 29 unsigned int *rsize) 30 30 { 31 - if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { 31 + if (*rsize >= 18 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { 32 32 hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n"); 33 33 rdesc[11] = rdesc[16] = 0xff; 34 34 rdesc[12] = rdesc[17] = 0x03;
+79 -51
drivers/hid/hid-huion.c
··· 84 84 0xC0 /* End Collection */ 85 85 }; 86 86 87 + /* Parameter indices */ 88 + enum huion_prm { 89 + HUION_PRM_X_LM = 1, 90 + HUION_PRM_Y_LM = 2, 91 + HUION_PRM_PRESSURE_LM = 4, 92 + HUION_PRM_RESOLUTION = 5, 93 + HUION_PRM_NUM 94 + }; 95 + 87 96 /* Driver data */ 88 97 struct huion_drvdata { 89 98 __u8 *rdesc; ··· 124 115 int rc; 125 116 struct usb_device *usb_dev = hid_to_usb_dev(hdev); 126 117 struct huion_drvdata *drvdata = hid_get_drvdata(hdev); 127 - __le16 buf[6]; 118 + __le16 *buf = NULL; 119 + size_t len; 120 + s32 params[HUION_PH_ID_NUM]; 121 + s32 resolution; 122 + __u8 *p; 123 + s32 v; 128 124 129 125 /* 130 126 * Read string descriptor containing tablet parameters. The specific ··· 137 123 * driver traffic. 138 124 * NOTE: This enables fully-functional tablet mode. 139 125 */ 126 + len = HUION_PRM_NUM * sizeof(*buf); 127 + buf = kmalloc(len, GFP_KERNEL); 128 + if (buf == NULL) { 129 + hid_err(hdev, "failed to allocate parameter buffer\n"); 130 + rc = -ENOMEM; 131 + goto cleanup; 132 + } 140 133 rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 141 134 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, 142 135 (USB_DT_STRING << 8) + 0x64, 143 - 0x0409, buf, sizeof(buf), 136 + 0x0409, buf, len, 144 137 USB_CTRL_GET_TIMEOUT); 145 - if (rc == -EPIPE) 146 - hid_warn(hdev, "device parameters not found\n"); 147 - else if (rc < 0) 148 - hid_warn(hdev, "failed to get device parameters: %d\n", rc); 149 - else if (rc != sizeof(buf)) 150 - hid_warn(hdev, "invalid device parameters\n"); 151 - else { 152 - s32 params[HUION_PH_ID_NUM]; 153 - s32 resolution; 154 - __u8 *p; 155 - s32 v; 138 + if (rc == -EPIPE) { 139 + hid_err(hdev, "device parameters not found\n"); 140 + rc = -ENODEV; 141 + goto cleanup; 142 + } else if (rc < 0) { 143 + hid_err(hdev, "failed to get device parameters: %d\n", rc); 144 + rc = -ENODEV; 145 + goto cleanup; 146 + } else if (rc != len) { 147 + hid_err(hdev, "invalid device parameters\n"); 148 + rc = -ENODEV; 149 + goto cleanup; 150 + } 156 151 157 - /* Extract device parameters */ 158 - params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]); 159 - params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]); 160 - params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]); 161 - resolution = le16_to_cpu(buf[5]); 162 - if (resolution == 0) { 163 - params[HUION_PH_ID_X_PM] = 0; 164 - params[HUION_PH_ID_Y_PM] = 0; 152 + /* Extract device parameters */ 153 + params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[HUION_PRM_X_LM]); 154 + params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[HUION_PRM_Y_LM]); 155 + params[HUION_PH_ID_PRESSURE_LM] = 156 + le16_to_cpu(buf[HUION_PRM_PRESSURE_LM]); 157 + resolution = le16_to_cpu(buf[HUION_PRM_RESOLUTION]); 158 + if (resolution == 0) { 159 + params[HUION_PH_ID_X_PM] = 0; 160 + params[HUION_PH_ID_Y_PM] = 0; 161 + } else { 162 + params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * 163 + 1000 / resolution; 164 + params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * 165 + 1000 / resolution; 166 + } 167 + 168 + /* Allocate fixed report descriptor */ 169 + drvdata->rdesc = devm_kmalloc(&hdev->dev, 170 + sizeof(huion_tablet_rdesc_template), 171 + GFP_KERNEL); 172 + if (drvdata->rdesc == NULL) { 173 + hid_err(hdev, "failed to allocate fixed rdesc\n"); 174 + rc = -ENOMEM; 175 + goto cleanup; 176 + } 177 + drvdata->rsize = sizeof(huion_tablet_rdesc_template); 178 + 179 + /* Format fixed report descriptor */ 180 + memcpy(drvdata->rdesc, huion_tablet_rdesc_template, 181 + drvdata->rsize); 182 + for (p = drvdata->rdesc; 183 + p <= drvdata->rdesc + drvdata->rsize - 4;) { 184 + if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && 185 + p[3] < sizeof(params)) { 186 + v = params[p[3]]; 187 + put_unaligned(cpu_to_le32(v), (s32 *)p); 188 + p += 4; 165 189 } else { 166 - params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * 167 - 1000 / resolution; 168 - params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * 169 - 1000 / resolution; 170 - } 171 - 172 - /* Allocate fixed report descriptor */ 173 - drvdata->rdesc = devm_kmalloc(&hdev->dev, 174 - sizeof(huion_tablet_rdesc_template), 175 - GFP_KERNEL); 176 - if (drvdata->rdesc == NULL) { 177 - hid_err(hdev, "failed to allocate fixed rdesc\n"); 178 - return -ENOMEM; 179 - } 180 - drvdata->rsize = sizeof(huion_tablet_rdesc_template); 181 - 182 - /* Format fixed report descriptor */ 183 - memcpy(drvdata->rdesc, huion_tablet_rdesc_template, 184 - drvdata->rsize); 185 - for (p = drvdata->rdesc; 186 - p <= drvdata->rdesc + drvdata->rsize - 4;) { 187 - if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && 188 - p[3] < sizeof(params)) { 189 - v = params[p[3]]; 190 - put_unaligned(cpu_to_le32(v), (s32 *)p); 191 - p += 4; 192 - } else { 193 - p++; 194 - } 190 + p++; 195 191 } 196 192 } 197 193 198 - return 0; 194 + rc = 0; 195 + 196 + cleanup: 197 + kfree(buf); 198 + return rc; 199 199 } 200 200 201 201 static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id)
+1 -1
drivers/hid/hid-kye.c
··· 300 300 * - change the button usage range to 4-7 for the extra 301 301 * buttons 302 302 */ 303 - if (*rsize >= 74 && 303 + if (*rsize >= 75 && 304 304 rdesc[61] == 0x05 && rdesc[62] == 0x08 && 305 305 rdesc[63] == 0x19 && rdesc[64] == 0x08 && 306 306 rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
+2 -2
drivers/hid/hid-lg.c
··· 345 345 struct usb_device_descriptor *udesc; 346 346 __u16 bcdDevice, rev_maj, rev_min; 347 347 348 - if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && 348 + if ((drv_data->quirks & LG_RDESC) && *rsize >= 91 && rdesc[83] == 0x26 && 349 349 rdesc[84] == 0x8c && rdesc[85] == 0x02) { 350 350 hid_info(hdev, 351 351 "fixing up Logitech keyboard report descriptor\n"); 352 352 rdesc[84] = rdesc[89] = 0x4d; 353 353 rdesc[85] = rdesc[90] = 0x10; 354 354 } 355 - if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 50 && 355 + if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 51 && 356 356 rdesc[32] == 0x81 && rdesc[33] == 0x06 && 357 357 rdesc[49] == 0x81 && rdesc[50] == 0x06) { 358 358 hid_info(hdev,
+2 -2
drivers/hid/hid-lg4ff.c
··· 451 451 drv_data = hid_get_drvdata(hid); 452 452 if (!drv_data) { 453 453 hid_err(hid, "Private driver data not found!\n"); 454 - return 0; 454 + return -EINVAL; 455 455 } 456 456 457 457 entry = drv_data->device_props; 458 458 if (!entry) { 459 459 hid_err(hid, "Device properties not found!\n"); 460 - return 0; 460 + return -EINVAL; 461 461 } 462 462 463 463 if (range == 0)
+7 -8
drivers/hid/hid-logitech-dj.c
··· 238 238 return; 239 239 } 240 240 241 - if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || 242 - (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { 243 - dev_err(&djrcv_hdev->dev, "%s: invalid device index:%d\n", 244 - __func__, dj_report->device_index); 245 - return; 246 - } 247 - 248 241 if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { 249 242 /* The device is already known. No need to reallocate it. */ 250 243 dbg_hid("%s: device is already known\n", __func__); ··· 550 557 if (!out_buf) 551 558 return -ENOMEM; 552 559 553 - if (count < DJREPORT_SHORT_LENGTH - 2) 560 + if (count > DJREPORT_SHORT_LENGTH - 2) 554 561 count = DJREPORT_SHORT_LENGTH - 2; 555 562 556 563 out_buf[0] = REPORT_ID_DJ_SHORT; ··· 683 690 * device (via hid_input_report() ) and return 1 so hid-core does not do 684 691 * anything else with it. 685 692 */ 693 + if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || 694 + (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { 695 + dev_err(&hdev->dev, "%s: invalid device index:%d\n", 696 + __func__, dj_report->device_index); 697 + return false; 698 + } 686 699 687 700 spin_lock_irqsave(&djrcv_dev->lock, flags); 688 701 if (dj_report->report_id == REPORT_ID_DJ_SHORT) {
+1 -1
drivers/hid/hid-monterey.c
··· 24 24 static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, 25 25 unsigned int *rsize) 26 26 { 27 - if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { 27 + if (*rsize >= 31 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { 28 28 hid_info(hdev, "fixing up button/consumer in HID report descriptor\n"); 29 29 rdesc[30] = 0x0c; 30 30 }
+1 -1
drivers/hid/hid-petalynx.c
··· 25 25 static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, 26 26 unsigned int *rsize) 27 27 { 28 - if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && 28 + if (*rsize >= 62 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && 29 29 rdesc[41] == 0x00 && rdesc[59] == 0x26 && 30 30 rdesc[60] == 0xf9 && rdesc[61] == 0x00) { 31 31 hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n");
+9 -4
drivers/hid/hid-rmi.c
··· 909 909 return ret; 910 910 } 911 911 912 - if (!test_bit(RMI_STARTED, &data->flags)) { 913 - hid_hw_stop(hdev); 914 - return -EIO; 915 - } 912 + if (!test_bit(RMI_STARTED, &data->flags)) 913 + /* 914 + * The device maybe in the bootloader if rmi_input_configured 915 + * failed to find F11 in the PDT. Print an error, but don't 916 + * return an error from rmi_probe so that hidraw will be 917 + * accessible from userspace. That way a userspace tool 918 + * can be used to reload working firmware on the touchpad. 919 + */ 920 + hid_err(hdev, "Device failed to be properly configured\n"); 916 921 917 922 return 0; 918 923 }
+11 -22
drivers/hid/hid-sensor-hub.c
··· 604 604 ret = -EINVAL; 605 605 goto err_stop_hw; 606 606 } 607 - sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt * 608 - sizeof(struct mfd_cell), 609 - GFP_KERNEL); 607 + sd->hid_sensor_hub_client_devs = devm_kzalloc(&hdev->dev, dev_cnt * 608 + sizeof(struct mfd_cell), 609 + GFP_KERNEL); 610 610 if (sd->hid_sensor_hub_client_devs == NULL) { 611 611 hid_err(hdev, "Failed to allocate memory for mfd cells\n"); 612 612 ret = -ENOMEM; ··· 618 618 619 619 if (collection->type == HID_COLLECTION_PHYSICAL) { 620 620 621 - hsdev = kzalloc(sizeof(*hsdev), GFP_KERNEL); 621 + hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev), 622 + GFP_KERNEL); 622 623 if (!hsdev) { 623 624 hid_err(hdev, "cannot allocate hid_sensor_hub_device\n"); 624 625 ret = -ENOMEM; 625 - goto err_no_mem; 626 + goto err_stop_hw; 626 627 } 627 628 hsdev->hdev = hdev; 628 629 hsdev->vendor_id = hdev->vendor; ··· 632 631 if (last_hsdev) 633 632 last_hsdev->end_collection_index = i; 634 633 last_hsdev = hsdev; 635 - name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x", 636 - collection->usage); 634 + name = devm_kasprintf(&hdev->dev, GFP_KERNEL, 635 + "HID-SENSOR-%x", 636 + collection->usage); 637 637 if (name == NULL) { 638 638 hid_err(hdev, "Failed MFD device name\n"); 639 639 ret = -ENOMEM; 640 - kfree(hsdev); 641 - goto err_no_mem; 640 + goto err_stop_hw; 642 641 } 643 642 sd->hid_sensor_hub_client_devs[ 644 643 sd->hid_sensor_client_cnt].id = ··· 662 661 ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, 663 662 sd->hid_sensor_client_cnt, NULL, 0, NULL); 664 663 if (ret < 0) 665 - goto err_no_mem; 664 + goto err_stop_hw; 666 665 667 666 return ret; 668 667 669 - err_no_mem: 670 - for (i = 0; i < sd->hid_sensor_client_cnt; ++i) { 671 - kfree(sd->hid_sensor_hub_client_devs[i].name); 672 - kfree(sd->hid_sensor_hub_client_devs[i].platform_data); 673 - } 674 - kfree(sd->hid_sensor_hub_client_devs); 675 668 err_stop_hw: 676 669 hid_hw_stop(hdev); 677 670 ··· 676 681 { 677 682 struct sensor_hub_data *data = hid_get_drvdata(hdev); 678 683 unsigned long flags; 679 - int i; 680 684 681 685 hid_dbg(hdev, " hardware removed\n"); 682 686 hid_hw_close(hdev); ··· 685 691 complete(&data->pending.ready); 686 692 spin_unlock_irqrestore(&data->lock, flags); 687 693 mfd_remove_devices(&hdev->dev); 688 - for (i = 0; i < data->hid_sensor_client_cnt; ++i) { 689 - kfree(data->hid_sensor_hub_client_devs[i].name); 690 - kfree(data->hid_sensor_hub_client_devs[i].platform_data); 691 - } 692 - kfree(data->hid_sensor_hub_client_devs); 693 694 hid_set_drvdata(hdev, NULL); 694 695 mutex_destroy(&data->mutex); 695 696 }
+1 -1
drivers/hid/hid-sunplus.c
··· 24 24 static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, 25 25 unsigned int *rsize) 26 26 { 27 - if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && 27 + if (*rsize >= 112 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && 28 28 rdesc[106] == 0x03) { 29 29 hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n"); 30 30 rdesc[105] = rdesc[110] = 0x03;