From 4cf9952ed5747fa62c26779e0964627c522f2e40 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 4 Nov 2019 10:08:56 +0100 Subject: [PATCH] 5.3-stable patches added patches: hid-fix-assumption-that-devices-have-inputs.patch hid-fix-error-message-in-hid_open_report.patch hid-i2c-hid-add-trekstor-primebook-c11b-to-descriptor-override.patch scsi-qla2xxx-fix-partial-flash-write-of-mbi.patch scsi-target-cxgbit-fix-cxgbit_fw4_ack.patch usb-gadget-reject-endpoints-with-0-maxpacket-value.patch usb-ldusb-fix-control-message-timeout.patch usb-ldusb-fix-ring-buffer-locking.patch usb-serial-whiteheat-fix-line-speed-endianness.patch usb-serial-whiteheat-fix-potential-slab-corruption.patch usb-storage-revert-commit-747668dbc061-usb-storage-set-virt_boundary_mask-to-avoid-sg-overflows.patch usb-xhci-fix-__le32-__le64-accessors-in-debugfs-code.patch usb-xhci-fix-immediate-data-transfer-endianness.patch xhci-fix-use-after-free-regression-in-xhci-clear-hub-tt-implementation.patch --- ...-assumption-that-devices-have-inputs.patch | 384 ++++++++++++++++++ ...fix-error-message-in-hid_open_report.patch | 60 +++ ...rimebook-c11b-to-descriptor-override.patch | 50 +++ ...a2xxx-fix-partial-flash-write-of-mbi.patch | 50 +++ ...csi-target-cxgbit-fix-cxgbit_fw4_ack.patch | 44 ++ queue-5.3/series | 14 + ...ect-endpoints-with-0-maxpacket-value.patch | 56 +++ ...sb-ldusb-fix-control-message-timeout.patch | 34 ++ .../usb-ldusb-fix-ring-buffer-locking.patch | 48 +++ ...-whiteheat-fix-line-speed-endianness.patch | 63 +++ ...teheat-fix-potential-slab-corruption.patch | 35 ++ ..._boundary_mask-to-avoid-sg-overflows.patch | 84 ++++ ...e32-__le64-accessors-in-debugfs-code.patch | 80 ++++ ...x-immediate-data-transfer-endianness.patch | 49 +++ ...-in-xhci-clear-hub-tt-implementation.patch | 124 ++++++ 15 files changed, 1175 insertions(+) create mode 100644 queue-5.3/hid-fix-assumption-that-devices-have-inputs.patch create mode 100644 queue-5.3/hid-fix-error-message-in-hid_open_report.patch create mode 100644 queue-5.3/hid-i2c-hid-add-trekstor-primebook-c11b-to-descriptor-override.patch create mode 100644 queue-5.3/scsi-qla2xxx-fix-partial-flash-write-of-mbi.patch create mode 100644 queue-5.3/scsi-target-cxgbit-fix-cxgbit_fw4_ack.patch create mode 100644 queue-5.3/usb-gadget-reject-endpoints-with-0-maxpacket-value.patch create mode 100644 queue-5.3/usb-ldusb-fix-control-message-timeout.patch create mode 100644 queue-5.3/usb-ldusb-fix-ring-buffer-locking.patch create mode 100644 queue-5.3/usb-serial-whiteheat-fix-line-speed-endianness.patch create mode 100644 queue-5.3/usb-serial-whiteheat-fix-potential-slab-corruption.patch create mode 100644 queue-5.3/usb-storage-revert-commit-747668dbc061-usb-storage-set-virt_boundary_mask-to-avoid-sg-overflows.patch create mode 100644 queue-5.3/usb-xhci-fix-__le32-__le64-accessors-in-debugfs-code.patch create mode 100644 queue-5.3/usb-xhci-fix-immediate-data-transfer-endianness.patch create mode 100644 queue-5.3/xhci-fix-use-after-free-regression-in-xhci-clear-hub-tt-implementation.patch diff --git a/queue-5.3/hid-fix-assumption-that-devices-have-inputs.patch b/queue-5.3/hid-fix-assumption-that-devices-have-inputs.patch new file mode 100644 index 00000000000..249fe44cd71 --- /dev/null +++ b/queue-5.3/hid-fix-assumption-that-devices-have-inputs.patch @@ -0,0 +1,384 @@ +From d9d4b1e46d9543a82c23f6df03f4ad697dab361b Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 3 Oct 2019 14:53:59 -0400 +Subject: HID: Fix assumption that devices have inputs + +From: Alan Stern + +commit d9d4b1e46d9543a82c23f6df03f4ad697dab361b upstream. + +The syzbot fuzzer found a slab-out-of-bounds write bug in the hid-gaff +driver. The problem is caused by the driver's assumption that the +device must have an input report. While this will be true for all +normal HID input devices, a suitably malicious device can violate the +assumption. + +The same assumption is present in over a dozen other HID drivers. +This patch fixes them by checking that the list of hid_inputs for the +hid_device is nonempty before allowing it to be used. + +Reported-and-tested-by: syzbot+403741a091bf41d4ae79@syzkaller.appspotmail.com +Signed-off-by: Alan Stern +CC: +Signed-off-by: Benjamin Tissoires +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-axff.c | 11 +++++++++-- + drivers/hid/hid-dr.c | 12 +++++++++--- + drivers/hid/hid-emsff.c | 12 +++++++++--- + drivers/hid/hid-gaff.c | 12 +++++++++--- + drivers/hid/hid-holtekff.c | 12 +++++++++--- + drivers/hid/hid-lg2ff.c | 12 +++++++++--- + drivers/hid/hid-lg3ff.c | 11 +++++++++-- + drivers/hid/hid-lg4ff.c | 11 +++++++++-- + drivers/hid/hid-lgff.c | 11 +++++++++-- + drivers/hid/hid-logitech-hidpp.c | 11 +++++++++-- + drivers/hid/hid-microsoft.c | 12 +++++++++--- + drivers/hid/hid-sony.c | 12 +++++++++--- + drivers/hid/hid-tmff.c | 12 +++++++++--- + drivers/hid/hid-zpff.c | 12 +++++++++--- + 14 files changed, 126 insertions(+), 37 deletions(-) + +--- a/drivers/hid/hid-axff.c ++++ b/drivers/hid/hid-axff.c +@@ -63,13 +63,20 @@ static int axff_init(struct hid_device * + { + struct axff_device *axff; + struct hid_report *report; +- struct hid_input *hidinput = list_first_entry(&hid->inputs, struct hid_input, list); ++ struct hid_input *hidinput; + struct list_head *report_list =&hid->report_enum[HID_OUTPUT_REPORT].report_list; +- struct input_dev *dev = hidinput->input; ++ struct input_dev *dev; + int field_count = 0; + int i, j; + int error; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_first_entry(&hid->inputs, struct hid_input, list); ++ dev = hidinput->input; ++ + if (list_empty(report_list)) { + hid_err(hid, "no output reports found\n"); + return -ENODEV; +--- a/drivers/hid/hid-dr.c ++++ b/drivers/hid/hid-dr.c +@@ -75,13 +75,19 @@ static int drff_init(struct hid_device * + { + struct drff_device *drff; + struct hid_report *report; +- struct hid_input *hidinput = list_first_entry(&hid->inputs, +- struct hid_input, list); ++ struct hid_input *hidinput; + struct list_head *report_list = + &hid->report_enum[HID_OUTPUT_REPORT].report_list; +- struct input_dev *dev = hidinput->input; ++ struct input_dev *dev; + int error; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_first_entry(&hid->inputs, struct hid_input, list); ++ dev = hidinput->input; ++ + if (list_empty(report_list)) { + hid_err(hid, "no output reports found\n"); + return -ENODEV; +--- a/drivers/hid/hid-emsff.c ++++ b/drivers/hid/hid-emsff.c +@@ -47,13 +47,19 @@ static int emsff_init(struct hid_device + { + struct emsff_device *emsff; + struct hid_report *report; +- struct hid_input *hidinput = list_first_entry(&hid->inputs, +- struct hid_input, list); ++ struct hid_input *hidinput; + struct list_head *report_list = + &hid->report_enum[HID_OUTPUT_REPORT].report_list; +- struct input_dev *dev = hidinput->input; ++ struct input_dev *dev; + int error; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_first_entry(&hid->inputs, struct hid_input, list); ++ dev = hidinput->input; ++ + if (list_empty(report_list)) { + hid_err(hid, "no output reports found\n"); + return -ENODEV; +--- a/drivers/hid/hid-gaff.c ++++ b/drivers/hid/hid-gaff.c +@@ -64,14 +64,20 @@ static int gaff_init(struct hid_device * + { + struct gaff_device *gaff; + struct hid_report *report; +- struct hid_input *hidinput = list_entry(hid->inputs.next, +- struct hid_input, list); ++ struct hid_input *hidinput; + struct list_head *report_list = + &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct list_head *report_ptr = report_list; +- struct input_dev *dev = hidinput->input; ++ struct input_dev *dev; + int error; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_entry(hid->inputs.next, struct hid_input, list); ++ dev = hidinput->input; ++ + if (list_empty(report_list)) { + hid_err(hid, "no output reports found\n"); + return -ENODEV; +--- a/drivers/hid/hid-holtekff.c ++++ b/drivers/hid/hid-holtekff.c +@@ -124,13 +124,19 @@ static int holtekff_init(struct hid_devi + { + struct holtekff_device *holtekff; + struct hid_report *report; +- struct hid_input *hidinput = list_entry(hid->inputs.next, +- struct hid_input, list); ++ struct hid_input *hidinput; + struct list_head *report_list = + &hid->report_enum[HID_OUTPUT_REPORT].report_list; +- struct input_dev *dev = hidinput->input; ++ struct input_dev *dev; + int error; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_entry(hid->inputs.next, struct hid_input, list); ++ dev = hidinput->input; ++ + if (list_empty(report_list)) { + hid_err(hid, "no output report found\n"); + return -ENODEV; +--- a/drivers/hid/hid-lg2ff.c ++++ b/drivers/hid/hid-lg2ff.c +@@ -50,11 +50,17 @@ int lg2ff_init(struct hid_device *hid) + { + struct lg2ff_device *lg2ff; + struct hid_report *report; +- struct hid_input *hidinput = list_entry(hid->inputs.next, +- struct hid_input, list); +- struct input_dev *dev = hidinput->input; ++ struct hid_input *hidinput; ++ struct input_dev *dev; + int error; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_entry(hid->inputs.next, struct hid_input, list); ++ dev = hidinput->input; ++ + /* Check that the report looks ok */ + report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7); + if (!report) +--- a/drivers/hid/hid-lg3ff.c ++++ b/drivers/hid/hid-lg3ff.c +@@ -117,12 +117,19 @@ static const signed short ff3_joystick_a + + int lg3ff_init(struct hid_device *hid) + { +- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct input_dev *dev = hidinput->input; ++ struct hid_input *hidinput; ++ struct input_dev *dev; + const signed short *ff_bits = ff3_joystick_ac; + int error; + int i; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_entry(hid->inputs.next, struct hid_input, list); ++ dev = hidinput->input; ++ + /* Check that the report looks ok */ + if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 35)) + return -ENODEV; +--- a/drivers/hid/hid-lg4ff.c ++++ b/drivers/hid/hid-lg4ff.c +@@ -1253,8 +1253,8 @@ static int lg4ff_handle_multimode_wheel( + + int lg4ff_init(struct hid_device *hid) + { +- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct input_dev *dev = hidinput->input; ++ struct hid_input *hidinput; ++ struct input_dev *dev; + struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct hid_report *report = list_entry(report_list->next, struct hid_report, list); + const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); +@@ -1266,6 +1266,13 @@ int lg4ff_init(struct hid_device *hid) + int mmode_ret, mmode_idx = -1; + u16 real_product_id; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_entry(hid->inputs.next, struct hid_input, list); ++ dev = hidinput->input; ++ + /* Check that the report looks ok */ + if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) + return -1; +--- a/drivers/hid/hid-lgff.c ++++ b/drivers/hid/hid-lgff.c +@@ -115,12 +115,19 @@ static void hid_lgff_set_autocenter(stru + + int lgff_init(struct hid_device* hid) + { +- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct input_dev *dev = hidinput->input; ++ struct hid_input *hidinput; ++ struct input_dev *dev; + const signed short *ff_bits = ff_joystick; + int error; + int i; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_entry(hid->inputs.next, struct hid_input, list); ++ dev = hidinput->input; ++ + /* Check that the report looks ok */ + if (!hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 7)) + return -ENODEV; +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -2084,8 +2084,8 @@ static void hidpp_ff_destroy(struct ff_d + static int hidpp_ff_init(struct hidpp_device *hidpp, u8 feature_index) + { + struct hid_device *hid = hidpp->hid_dev; +- struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); +- struct input_dev *dev = hidinput->input; ++ struct hid_input *hidinput; ++ struct input_dev *dev; + const struct usb_device_descriptor *udesc = &(hid_to_usb_dev(hid)->descriptor); + const u16 bcdDevice = le16_to_cpu(udesc->bcdDevice); + struct ff_device *ff; +@@ -2094,6 +2094,13 @@ static int hidpp_ff_init(struct hidpp_de + int error, j, num_slots; + u8 version; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_entry(hid->inputs.next, struct hid_input, list); ++ dev = hidinput->input; ++ + if (!dev) { + hid_err(hid, "Struct input_dev not set!\n"); + return -EINVAL; +--- a/drivers/hid/hid-microsoft.c ++++ b/drivers/hid/hid-microsoft.c +@@ -328,11 +328,17 @@ static int ms_play_effect(struct input_d + + static int ms_init_ff(struct hid_device *hdev) + { +- struct hid_input *hidinput = list_entry(hdev->inputs.next, +- struct hid_input, list); +- struct input_dev *input_dev = hidinput->input; ++ struct hid_input *hidinput; ++ struct input_dev *input_dev; + struct ms_data *ms = hid_get_drvdata(hdev); + ++ if (list_empty(&hdev->inputs)) { ++ hid_err(hdev, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_entry(hdev->inputs.next, struct hid_input, list); ++ input_dev = hidinput->input; ++ + if (!(ms->quirks & MS_QUIRK_FF)) + return 0; + +--- a/drivers/hid/hid-sony.c ++++ b/drivers/hid/hid-sony.c +@@ -2254,9 +2254,15 @@ static int sony_play_effect(struct input + + static int sony_init_ff(struct sony_sc *sc) + { +- struct hid_input *hidinput = list_entry(sc->hdev->inputs.next, +- struct hid_input, list); +- struct input_dev *input_dev = hidinput->input; ++ struct hid_input *hidinput; ++ struct input_dev *input_dev; ++ ++ if (list_empty(&sc->hdev->inputs)) { ++ hid_err(sc->hdev, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_entry(sc->hdev->inputs.next, struct hid_input, list); ++ input_dev = hidinput->input; + + input_set_capability(input_dev, EV_FF, FF_RUMBLE); + return input_ff_create_memless(input_dev, NULL, sony_play_effect); +--- a/drivers/hid/hid-tmff.c ++++ b/drivers/hid/hid-tmff.c +@@ -124,12 +124,18 @@ static int tmff_init(struct hid_device * + struct tmff_device *tmff; + struct hid_report *report; + struct list_head *report_list; +- struct hid_input *hidinput = list_entry(hid->inputs.next, +- struct hid_input, list); +- struct input_dev *input_dev = hidinput->input; ++ struct hid_input *hidinput; ++ struct input_dev *input_dev; + int error; + int i; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_entry(hid->inputs.next, struct hid_input, list); ++ input_dev = hidinput->input; ++ + tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL); + if (!tmff) + return -ENOMEM; +--- a/drivers/hid/hid-zpff.c ++++ b/drivers/hid/hid-zpff.c +@@ -54,11 +54,17 @@ static int zpff_init(struct hid_device * + { + struct zpff_device *zpff; + struct hid_report *report; +- struct hid_input *hidinput = list_entry(hid->inputs.next, +- struct hid_input, list); +- struct input_dev *dev = hidinput->input; ++ struct hid_input *hidinput; ++ struct input_dev *dev; + int i, error; + ++ if (list_empty(&hid->inputs)) { ++ hid_err(hid, "no inputs found\n"); ++ return -ENODEV; ++ } ++ hidinput = list_entry(hid->inputs.next, struct hid_input, list); ++ dev = hidinput->input; ++ + for (i = 0; i < 4; i++) { + report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1); + if (!report) diff --git a/queue-5.3/hid-fix-error-message-in-hid_open_report.patch b/queue-5.3/hid-fix-error-message-in-hid_open_report.patch new file mode 100644 index 00000000000..081c260478a --- /dev/null +++ b/queue-5.3/hid-fix-error-message-in-hid_open_report.patch @@ -0,0 +1,60 @@ +From b3a81c777dcb093020680490ab970d85e2f6f04f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= +Date: Fri, 23 Aug 2019 21:15:27 +0200 +Subject: HID: fix error message in hid_open_report() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michał Mirosław + +commit b3a81c777dcb093020680490ab970d85e2f6f04f upstream. + +On HID report descriptor parsing error the code displays bogus +pointer instead of error offset (subtracts start=NULL from end). +Make the message more useful by displaying correct error offset +and include total buffer size for reference. + +This was carried over from ancient times - "Fixed" commit just +promoted the message from DEBUG to ERROR. + +Cc: stable@vger.kernel.org +Fixes: 8c3d52fc393b ("HID: make parser more verbose about parsing errors by default") +Signed-off-by: Michał Mirosław +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-core.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1139,6 +1139,7 @@ int hid_open_report(struct hid_device *d + __u8 *start; + __u8 *buf; + __u8 *end; ++ __u8 *next; + int ret; + static int (*dispatch_type[])(struct hid_parser *parser, + struct hid_item *item) = { +@@ -1192,7 +1193,8 @@ int hid_open_report(struct hid_device *d + device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; + + ret = -EINVAL; +- while ((start = fetch_item(start, end, &item)) != NULL) { ++ while ((next = fetch_item(start, end, &item)) != NULL) { ++ start = next; + + if (item.format != HID_ITEM_FORMAT_SHORT) { + hid_err(device, "unexpected long global item\n"); +@@ -1230,7 +1232,8 @@ int hid_open_report(struct hid_device *d + } + } + +- hid_err(device, "item fetching failed at offset %d\n", (int)(end - start)); ++ hid_err(device, "item fetching failed at offset %u/%u\n", ++ size - (unsigned int)(end - start), size); + err: + kfree(parser->collection_stack); + alloc_err: diff --git a/queue-5.3/hid-i2c-hid-add-trekstor-primebook-c11b-to-descriptor-override.patch b/queue-5.3/hid-i2c-hid-add-trekstor-primebook-c11b-to-descriptor-override.patch new file mode 100644 index 00000000000..a16d617a2c1 --- /dev/null +++ b/queue-5.3/hid-i2c-hid-add-trekstor-primebook-c11b-to-descriptor-override.patch @@ -0,0 +1,50 @@ +From 09f3dbe474735df13dd8a66d3d1231048d9b373f Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 7 Oct 2019 20:56:26 +0200 +Subject: HID: i2c-hid: add Trekstor Primebook C11B to descriptor override + +From: Hans de Goede + +commit 09f3dbe474735df13dd8a66d3d1231048d9b373f upstream. + +The Primebook C11B uses the SIPODEV SP1064 touchpad. There are 2 versions +of this 2-in-1 and the touchpad in the older version does not supply +descriptors, so it has to be added to the override list. + +Cc: stable@vger.kernel.org +Signed-off-by: Hans de Goede +Signed-off-by: Benjamin Tissoires +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c ++++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +@@ -323,6 +323,25 @@ static const struct dmi_system_id i2c_hi + .driver_data = (void *)&sipodev_desc + }, + { ++ /* ++ * There are at least 2 Primebook C11B versions, the older ++ * version has a product-name of "Primebook C11B", and a ++ * bios version / release / firmware revision of: ++ * V2.1.2 / 05/03/2018 / 18.2 ++ * The new version has "PRIMEBOOK C11B" as product-name and a ++ * bios version / release / firmware revision of: ++ * CFALKSW05_BIOS_V1.1.2 / 11/19/2018 / 19.2 ++ * Only the older version needs this quirk, note the newer ++ * version will not match as it has a different product-name. ++ */ ++ .ident = "Trekstor Primebook C11B", ++ .matches = { ++ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), ++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Primebook C11B"), ++ }, ++ .driver_data = (void *)&sipodev_desc ++ }, ++ { + .ident = "Direkt-Tek DTLAPY116-2", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"), diff --git a/queue-5.3/scsi-qla2xxx-fix-partial-flash-write-of-mbi.patch b/queue-5.3/scsi-qla2xxx-fix-partial-flash-write-of-mbi.patch new file mode 100644 index 00000000000..ef403e11ff8 --- /dev/null +++ b/queue-5.3/scsi-qla2xxx-fix-partial-flash-write-of-mbi.patch @@ -0,0 +1,50 @@ +From 8d8b83f5be2a3bdac3695a94e6cb5e50bd114869 Mon Sep 17 00:00:00 2001 +From: Quinn Tran +Date: Tue, 22 Oct 2019 12:36:43 -0700 +Subject: scsi: qla2xxx: Fix partial flash write of MBI + +From: Quinn Tran + +commit 8d8b83f5be2a3bdac3695a94e6cb5e50bd114869 upstream. + +For new adapters with multiple flash regions to write to, current code +allows FW & Boot regions to be written, while other regions are blocked via +sysfs. The fix is to block all flash read/write through sysfs interface. + +Fixes: e81d1bcbde06 ("scsi: qla2xxx: Further limit FLASH region write access from SysFS") +Cc: stable@vger.kernel.org # 5.2 +Link: https://lore.kernel.org/r/20191022193643.7076-3-hmadhani@marvell.com +Signed-off-by: Quinn Tran +Signed-off-by: Girish Basrur +Signed-off-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_attr.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_attr.c ++++ b/drivers/scsi/qla2xxx/qla_attr.c +@@ -441,9 +441,6 @@ qla2x00_sysfs_write_optrom_ctl(struct fi + valid = 0; + if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0) + valid = 1; +- else if (start == (ha->flt_region_boot * 4) || +- start == (ha->flt_region_fw * 4)) +- valid = 1; + else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) + valid = 1; + if (!valid) { +@@ -491,8 +488,10 @@ qla2x00_sysfs_write_optrom_ctl(struct fi + "Writing flash region -- 0x%x/0x%x.\n", + ha->optrom_region_start, ha->optrom_region_size); + +- ha->isp_ops->write_optrom(vha, ha->optrom_buffer, ++ rval = ha->isp_ops->write_optrom(vha, ha->optrom_buffer, + ha->optrom_region_start, ha->optrom_region_size); ++ if (rval) ++ rval = -EIO; + break; + default: + rval = -EINVAL; diff --git a/queue-5.3/scsi-target-cxgbit-fix-cxgbit_fw4_ack.patch b/queue-5.3/scsi-target-cxgbit-fix-cxgbit_fw4_ack.patch new file mode 100644 index 00000000000..a318a828ecb --- /dev/null +++ b/queue-5.3/scsi-target-cxgbit-fix-cxgbit_fw4_ack.patch @@ -0,0 +1,44 @@ +From fc5b220b2dcf8b512d9bd46fd17f82257e49bf89 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Wed, 23 Oct 2019 13:21:50 -0700 +Subject: scsi: target: cxgbit: Fix cxgbit_fw4_ack() + +From: Bart Van Assche + +commit fc5b220b2dcf8b512d9bd46fd17f82257e49bf89 upstream. + +Use the pointer 'p' after having tested that pointer instead of before. + +Fixes: 5cadafb236df ("target/cxgbit: Fix endianness annotations") +Cc: Varun Prakash +Cc: Nicholas Bellinger +Cc: +Link: https://lore.kernel.org/r/20191023202150.22173-1-bvanassche@acm.org +Reported-by: Dan Carpenter +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/cxgbit/cxgbit_cm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/target/iscsi/cxgbit/cxgbit_cm.c ++++ b/drivers/target/iscsi/cxgbit/cxgbit_cm.c +@@ -1831,7 +1831,7 @@ static void cxgbit_fw4_ack(struct cxgbit + + while (credits) { + struct sk_buff *p = cxgbit_sock_peek_wr(csk); +- const u32 csum = (__force u32)p->csum; ++ u32 csum; + + if (unlikely(!p)) { + pr_err("csk 0x%p,%u, cr %u,%u+%u, empty.\n", +@@ -1840,6 +1840,7 @@ static void cxgbit_fw4_ack(struct cxgbit + break; + } + ++ csum = (__force u32)p->csum; + if (unlikely(credits < csum)) { + pr_warn("csk 0x%p,%u, cr %u,%u+%u, < %u.\n", + csk, csk->tid, diff --git a/queue-5.3/series b/queue-5.3/series index d82bad0bff1..4a8b9ab1179 100644 --- a/queue-5.3/series +++ b/queue-5.3/series @@ -101,3 +101,17 @@ alsa-hda-realtek-add-support-for-alc623.patch ath10k-fix-latency-issue-for-qca988x.patch uas-revert-commit-3ae62a42090f-uas-fix-alignment-of-scatter-gather-segments.patch nl80211-fix-validation-of-mesh-path-nexthop.patch +usb-gadget-reject-endpoints-with-0-maxpacket-value.patch +usb-storage-revert-commit-747668dbc061-usb-storage-set-virt_boundary_mask-to-avoid-sg-overflows.patch +usb-ldusb-fix-ring-buffer-locking.patch +usb-ldusb-fix-control-message-timeout.patch +usb-xhci-fix-immediate-data-transfer-endianness.patch +usb-xhci-fix-__le32-__le64-accessors-in-debugfs-code.patch +usb-serial-whiteheat-fix-potential-slab-corruption.patch +usb-serial-whiteheat-fix-line-speed-endianness.patch +xhci-fix-use-after-free-regression-in-xhci-clear-hub-tt-implementation.patch +scsi-qla2xxx-fix-partial-flash-write-of-mbi.patch +scsi-target-cxgbit-fix-cxgbit_fw4_ack.patch +hid-i2c-hid-add-trekstor-primebook-c11b-to-descriptor-override.patch +hid-fix-assumption-that-devices-have-inputs.patch +hid-fix-error-message-in-hid_open_report.patch diff --git a/queue-5.3/usb-gadget-reject-endpoints-with-0-maxpacket-value.patch b/queue-5.3/usb-gadget-reject-endpoints-with-0-maxpacket-value.patch new file mode 100644 index 00000000000..bbe11962891 --- /dev/null +++ b/queue-5.3/usb-gadget-reject-endpoints-with-0-maxpacket-value.patch @@ -0,0 +1,56 @@ +From 54f83b8c8ea9b22082a496deadf90447a326954e Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Mon, 28 Oct 2019 10:54:26 -0400 +Subject: USB: gadget: Reject endpoints with 0 maxpacket value + +From: Alan Stern + +commit 54f83b8c8ea9b22082a496deadf90447a326954e upstream. + +Endpoints with a maxpacket length of 0 are probably useless. They +can't transfer any data, and it's not at all unlikely that a UDC will +crash or hang when trying to handle a non-zero-length usb_request for +such an endpoint. Indeed, dummy-hcd gets a divide error when trying +to calculate the remainder of a transfer length by the maxpacket +value, as discovered by the syzbot fuzzer. + +Currently the gadget core does not check for endpoints having a +maxpacket value of 0. This patch adds a check to usb_ep_enable(), +preventing such endpoints from being used. + +As far as I know, none of the gadget drivers in the kernel tries to +create an endpoint with maxpacket = 0, but until now there has been +nothing to prevent userspace programs under gadgetfs or configfs from +doing it. + +Signed-off-by: Alan Stern +Reported-and-tested-by: syzbot+8ab8bf161038a8768553@syzkaller.appspotmail.com +CC: +Acked-by: Felipe Balbi +Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1910281052370.1485-100000@iolanthe.rowland.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/udc/core.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -98,6 +98,17 @@ int usb_ep_enable(struct usb_ep *ep) + if (ep->enabled) + goto out; + ++ /* UDC drivers can't handle endpoints with maxpacket size 0 */ ++ if (usb_endpoint_maxp(ep->desc) == 0) { ++ /* ++ * We should log an error message here, but we can't call ++ * dev_err() because there's no way to find the gadget ++ * given only ep. ++ */ ++ ret = -EINVAL; ++ goto out; ++ } ++ + ret = ep->ops->enable(ep, ep->desc); + if (ret) + goto out; diff --git a/queue-5.3/usb-ldusb-fix-control-message-timeout.patch b/queue-5.3/usb-ldusb-fix-control-message-timeout.patch new file mode 100644 index 00000000000..0ad54c41924 --- /dev/null +++ b/queue-5.3/usb-ldusb-fix-control-message-timeout.patch @@ -0,0 +1,34 @@ +From 52403cfbc635d28195167618690595013776ebde Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 22 Oct 2019 17:31:27 +0200 +Subject: USB: ldusb: fix control-message timeout + +From: Johan Hovold + +commit 52403cfbc635d28195167618690595013776ebde upstream. + +USB control-message timeouts are specified in milliseconds, not jiffies. +Waiting 83 minutes for a transfer to complete is a bit excessive. + +Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") +Cc: stable # 2.6.13 +Reported-by: syzbot+a4fbb3bb76cda0ea4e58@syzkaller.appspotmail.com +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20191022153127.22295-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/ldusb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/misc/ldusb.c ++++ b/drivers/usb/misc/ldusb.c +@@ -580,7 +580,7 @@ static ssize_t ld_usb_write(struct file + 1 << 8, 0, + dev->interrupt_out_buffer, + bytes_to_write, +- USB_CTRL_SET_TIMEOUT * HZ); ++ USB_CTRL_SET_TIMEOUT); + if (retval < 0) + dev_err(&dev->intf->dev, + "Couldn't submit HID_REQ_SET_REPORT %d\n", diff --git a/queue-5.3/usb-ldusb-fix-ring-buffer-locking.patch b/queue-5.3/usb-ldusb-fix-ring-buffer-locking.patch new file mode 100644 index 00000000000..f6605be2705 --- /dev/null +++ b/queue-5.3/usb-ldusb-fix-ring-buffer-locking.patch @@ -0,0 +1,48 @@ +From d98ee2a19c3334e9343df3ce254b496f1fc428eb Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 22 Oct 2019 16:32:02 +0200 +Subject: USB: ldusb: fix ring-buffer locking + +From: Johan Hovold + +commit d98ee2a19c3334e9343df3ce254b496f1fc428eb upstream. + +The custom ring-buffer implementation was merged without any locking or +explicit memory barriers, but a spinlock was later added by commit +9d33efd9a791 ("USB: ldusb bugfix"). + +The lock did not cover the update of the tail index once the entry had +been processed, something which could lead to memory corruption on +weakly ordered architectures or due to compiler optimisations. + +Specifically, a completion handler running on another CPU might observe +the incremented tail index and update the entry before ld_usb_read() is +done with it. + +Fixes: 2824bd250f0b ("[PATCH] USB: add ldusb driver") +Fixes: 9d33efd9a791 ("USB: ldusb bugfix") +Cc: stable # 2.6.13 +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20191022143203.5260-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/ldusb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/misc/ldusb.c ++++ b/drivers/usb/misc/ldusb.c +@@ -495,11 +495,11 @@ static ssize_t ld_usb_read(struct file * + retval = -EFAULT; + goto unlock_exit; + } +- dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size; +- + retval = bytes_to_read; + + spin_lock_irq(&dev->rbsl); ++ dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size; ++ + if (dev->buffer_overflow) { + dev->buffer_overflow = 0; + spin_unlock_irq(&dev->rbsl); diff --git a/queue-5.3/usb-serial-whiteheat-fix-line-speed-endianness.patch b/queue-5.3/usb-serial-whiteheat-fix-line-speed-endianness.patch new file mode 100644 index 00000000000..60cfe6b82e9 --- /dev/null +++ b/queue-5.3/usb-serial-whiteheat-fix-line-speed-endianness.patch @@ -0,0 +1,63 @@ +From 84968291d7924261c6a0624b9a72f952398e258b Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 29 Oct 2019 11:23:54 +0100 +Subject: USB: serial: whiteheat: fix line-speed endianness + +From: Johan Hovold + +commit 84968291d7924261c6a0624b9a72f952398e258b upstream. + +Add missing endianness conversion when setting the line speed so that +this driver might work also on big-endian machines. + +Also use an unsigned format specifier in the corresponding debug +message. + +Signed-off-by: Johan Hovold +Cc: stable +Link: https://lore.kernel.org/r/20191029102354.2733-3-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/whiteheat.c | 9 ++++++--- + drivers/usb/serial/whiteheat.h | 2 +- + 2 files changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/usb/serial/whiteheat.c ++++ b/drivers/usb/serial/whiteheat.c +@@ -636,6 +636,7 @@ static void firm_setup_port(struct tty_s + struct device *dev = &port->dev; + struct whiteheat_port_settings port_settings; + unsigned int cflag = tty->termios.c_cflag; ++ speed_t baud; + + port_settings.port = port->port_number + 1; + +@@ -696,11 +697,13 @@ static void firm_setup_port(struct tty_s + dev_dbg(dev, "%s - XON = %2x, XOFF = %2x\n", __func__, port_settings.xon, port_settings.xoff); + + /* get the baud rate wanted */ +- port_settings.baud = tty_get_baud_rate(tty); +- dev_dbg(dev, "%s - baud rate = %d\n", __func__, port_settings.baud); ++ baud = tty_get_baud_rate(tty); ++ port_settings.baud = cpu_to_le32(baud); ++ dev_dbg(dev, "%s - baud rate = %u\n", __func__, baud); + + /* fixme: should set validated settings */ +- tty_encode_baud_rate(tty, port_settings.baud, port_settings.baud); ++ tty_encode_baud_rate(tty, baud, baud); ++ + /* handle any settings that aren't specified in the tty structure */ + port_settings.lloop = 0; + +--- a/drivers/usb/serial/whiteheat.h ++++ b/drivers/usb/serial/whiteheat.h +@@ -87,7 +87,7 @@ struct whiteheat_simple { + + struct whiteheat_port_settings { + __u8 port; /* port number (1 to N) */ +- __u32 baud; /* any value 7 - 460800, firmware calculates ++ __le32 baud; /* any value 7 - 460800, firmware calculates + best fit; arrives little endian */ + __u8 bits; /* 5, 6, 7, or 8 */ + __u8 stop; /* 1 or 2, default 1 (2 = 1.5 if bits = 5) */ diff --git a/queue-5.3/usb-serial-whiteheat-fix-potential-slab-corruption.patch b/queue-5.3/usb-serial-whiteheat-fix-potential-slab-corruption.patch new file mode 100644 index 00000000000..6c6106fbed1 --- /dev/null +++ b/queue-5.3/usb-serial-whiteheat-fix-potential-slab-corruption.patch @@ -0,0 +1,35 @@ +From 1251dab9e0a2c4d0d2d48370ba5baa095a5e8774 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 29 Oct 2019 11:23:53 +0100 +Subject: USB: serial: whiteheat: fix potential slab corruption + +From: Johan Hovold + +commit 1251dab9e0a2c4d0d2d48370ba5baa095a5e8774 upstream. + +Fix a user-controlled slab buffer overflow due to a missing sanity check +on the bulk-out transfer buffer used for control requests. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20191029102354.2733-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/whiteheat.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/usb/serial/whiteheat.c ++++ b/drivers/usb/serial/whiteheat.c +@@ -559,6 +559,10 @@ static int firm_send_command(struct usb_ + + command_port = port->serial->port[COMMAND_PORT]; + command_info = usb_get_serial_port_data(command_port); ++ ++ if (command_port->bulk_out_size < datasize + 1) ++ return -EIO; ++ + mutex_lock(&command_info->mutex); + command_info->command_finished = false; + diff --git a/queue-5.3/usb-storage-revert-commit-747668dbc061-usb-storage-set-virt_boundary_mask-to-avoid-sg-overflows.patch b/queue-5.3/usb-storage-revert-commit-747668dbc061-usb-storage-set-virt_boundary_mask-to-avoid-sg-overflows.patch new file mode 100644 index 00000000000..aa2cc125cc7 --- /dev/null +++ b/queue-5.3/usb-storage-revert-commit-747668dbc061-usb-storage-set-virt_boundary_mask-to-avoid-sg-overflows.patch @@ -0,0 +1,84 @@ +From 9a976949613132977098fc49510b46fa8678d864 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Mon, 21 Oct 2019 11:48:06 -0400 +Subject: usb-storage: Revert commit 747668dbc061 ("usb-storage: Set virt_boundary_mask to avoid SG overflows") + +From: Alan Stern + +commit 9a976949613132977098fc49510b46fa8678d864 upstream. + +Commit 747668dbc061 ("usb-storage: Set virt_boundary_mask to avoid SG +overflows") attempted to solve a problem involving scatter-gather I/O +and USB/IP by setting the virt_boundary_mask for mass-storage devices. + +However, it now turns out that this interacts badly with commit +09324d32d2a0 ("block: force an unlimited segment size on queues with a +virt boundary"), which was added later. A typical error message is: + + ehci-pci 0000:00:13.2: swiotlb buffer is full (sz: 327680 bytes), + total 32768 (slots), used 97 (slots) + +There is no longer any reason to keep the virt_boundary_mask setting +for usb-storage. It was needed in the first place only for handling +devices with a block size smaller than the maxpacket size and where +the host controller was not capable of fully general scatter-gather +operation (that is, able to merge two SG segments into a single USB +packet). But: + + High-speed or slower connections never use a bulk maxpacket + value larger than 512; + + The SCSI layer does not handle block devices with a block size + smaller than 512 bytes; + + All the host controllers capable of SuperSpeed operation can + handle fully general SG; + + Since commit ea44d190764b ("usbip: Implement SG support to + vhci-hcd and stub driver") was merged, the USB/IP driver can + also handle SG. + +Therefore all supported device/controller combinations should be okay +with no need for any special virt_boundary_mask. So in order to fix +the swiotlb problem, this patch reverts commit 747668dbc061. + +Reported-and-tested-by: Piergiorgio Sartor +Link: https://marc.info/?l=linux-usb&m=157134199501202&w=2 +Signed-off-by: Alan Stern +CC: Seth Bollinger +CC: +Fixes: 747668dbc061 ("usb-storage: Set virt_boundary_mask to avoid SG overflows") +Acked-by: Christoph Hellwig +Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1910211145520.1673-100000@iolanthe.rowland.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/scsiglue.c | 10 ---------- + 1 file changed, 10 deletions(-) + +--- a/drivers/usb/storage/scsiglue.c ++++ b/drivers/usb/storage/scsiglue.c +@@ -67,7 +67,6 @@ static const char* host_info(struct Scsi + static int slave_alloc (struct scsi_device *sdev) + { + struct us_data *us = host_to_us(sdev->host); +- int maxp; + + /* + * Set the INQUIRY transfer length to 36. We don't use any of +@@ -77,15 +76,6 @@ static int slave_alloc (struct scsi_devi + sdev->inquiry_len = 36; + + /* +- * USB has unusual scatter-gather requirements: the length of each +- * scatterlist element except the last must be divisible by the +- * Bulk maxpacket value. Fortunately this value is always a +- * power of 2. Inform the block layer about this requirement. +- */ +- maxp = usb_maxpacket(us->pusb_dev, us->recv_bulk_pipe, 0); +- blk_queue_virt_boundary(sdev->request_queue, maxp - 1); +- +- /* + * Some host controllers may have alignment requirements. + * We'll play it safe by requiring 512-byte alignment always. + */ diff --git a/queue-5.3/usb-xhci-fix-__le32-__le64-accessors-in-debugfs-code.patch b/queue-5.3/usb-xhci-fix-__le32-__le64-accessors-in-debugfs-code.patch new file mode 100644 index 00000000000..15622f67452 --- /dev/null +++ b/queue-5.3/usb-xhci-fix-__le32-__le64-accessors-in-debugfs-code.patch @@ -0,0 +1,80 @@ +From d5501d5c29a2e684640507cfee428178d6fd82ca Mon Sep 17 00:00:00 2001 +From: "Ben Dooks (Codethink)" +Date: Fri, 25 Oct 2019 17:30:29 +0300 +Subject: usb: xhci: fix __le32/__le64 accessors in debugfs code + +From: Ben Dooks (Codethink) + +commit d5501d5c29a2e684640507cfee428178d6fd82ca upstream. + +It looks like some of the xhci debug code is passing u32 to functions +directly from __le32/__le64 fields. +Fix this by using le{32,64}_to_cpu() on these to fix the following +sparse warnings; + +xhci-debugfs.c:205:62: warning: incorrect type in argument 1 (different base types) +xhci-debugfs.c:205:62: expected unsigned int [usertype] field0 +xhci-debugfs.c:205:62: got restricted __le32 +xhci-debugfs.c:206:62: warning: incorrect type in argument 2 (different base types) +xhci-debugfs.c:206:62: expected unsigned int [usertype] field1 +xhci-debugfs.c:206:62: got restricted __le32 +... + +[Trim down commit message, sparse warnings were similar -Mathias] +Cc: # 4.15+ +Signed-off-by: Ben Dooks +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/1572013829-14044-4-git-send-email-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-debugfs.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/drivers/usb/host/xhci-debugfs.c ++++ b/drivers/usb/host/xhci-debugfs.c +@@ -202,10 +202,10 @@ static void xhci_ring_dump_segment(struc + trb = &seg->trbs[i]; + dma = seg->dma + i * sizeof(*trb); + seq_printf(s, "%pad: %s\n", &dma, +- xhci_decode_trb(trb->generic.field[0], +- trb->generic.field[1], +- trb->generic.field[2], +- trb->generic.field[3])); ++ xhci_decode_trb(le32_to_cpu(trb->generic.field[0]), ++ le32_to_cpu(trb->generic.field[1]), ++ le32_to_cpu(trb->generic.field[2]), ++ le32_to_cpu(trb->generic.field[3]))); + } + } + +@@ -263,10 +263,10 @@ static int xhci_slot_context_show(struct + xhci = hcd_to_xhci(bus_to_hcd(dev->udev->bus)); + slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx); + seq_printf(s, "%pad: %s\n", &dev->out_ctx->dma, +- xhci_decode_slot_context(slot_ctx->dev_info, +- slot_ctx->dev_info2, +- slot_ctx->tt_info, +- slot_ctx->dev_state)); ++ xhci_decode_slot_context(le32_to_cpu(slot_ctx->dev_info), ++ le32_to_cpu(slot_ctx->dev_info2), ++ le32_to_cpu(slot_ctx->tt_info), ++ le32_to_cpu(slot_ctx->dev_state))); + + return 0; + } +@@ -286,10 +286,10 @@ static int xhci_endpoint_context_show(st + ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, dci); + dma = dev->out_ctx->dma + dci * CTX_SIZE(xhci->hcc_params); + seq_printf(s, "%pad: %s\n", &dma, +- xhci_decode_ep_context(ep_ctx->ep_info, +- ep_ctx->ep_info2, +- ep_ctx->deq, +- ep_ctx->tx_info)); ++ xhci_decode_ep_context(le32_to_cpu(ep_ctx->ep_info), ++ le32_to_cpu(ep_ctx->ep_info2), ++ le64_to_cpu(ep_ctx->deq), ++ le32_to_cpu(ep_ctx->tx_info))); + } + + return 0; diff --git a/queue-5.3/usb-xhci-fix-immediate-data-transfer-endianness.patch b/queue-5.3/usb-xhci-fix-immediate-data-transfer-endianness.patch new file mode 100644 index 00000000000..affe23cb662 --- /dev/null +++ b/queue-5.3/usb-xhci-fix-immediate-data-transfer-endianness.patch @@ -0,0 +1,49 @@ +From bfa3dbb343f664573292afb9e44f9abeb81a19de Mon Sep 17 00:00:00 2001 +From: Samuel Holland +Date: Fri, 25 Oct 2019 17:30:28 +0300 +Subject: usb: xhci: fix Immediate Data Transfer endianness + +From: Samuel Holland + +commit bfa3dbb343f664573292afb9e44f9abeb81a19de upstream. + +The arguments to queue_trb are always byteswapped to LE for placement in +the ring, but this should not happen in the case of immediate data; the +bytes copied out of transfer_buffer are already in the correct order. +Add a complementary byteswap so the bytes end up in the ring correctly. + +This was observed on BE ppc64 with a "Texas Instruments TUSB73x0 +SuperSpeed USB 3.0 xHCI Host Controller [104c:8241]" as a ch341 +usb-serial adapter ("1a86:7523 QinHeng Electronics HL-340 USB-Serial +adapter") always transmitting the same character (generally NUL) over +the serial link regardless of the key pressed. + +Cc: # 5.2+ +Fixes: 33e39350ebd2 ("usb: xhci: add Immediate Data Transfer support") +Signed-off-by: Samuel Holland +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/1572013829-14044-3-git-send-email-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -3330,6 +3330,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd * + if (xhci_urb_suitable_for_idt(urb)) { + memcpy(&send_addr, urb->transfer_buffer, + trb_buff_len); ++ le64_to_cpus(&send_addr); + field |= TRB_IDT; + } + } +@@ -3475,6 +3476,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd * + if (xhci_urb_suitable_for_idt(urb)) { + memcpy(&addr, urb->transfer_buffer, + urb->transfer_buffer_length); ++ le64_to_cpus(&addr); + field |= TRB_IDT; + } else { + addr = (u64) urb->transfer_dma; diff --git a/queue-5.3/xhci-fix-use-after-free-regression-in-xhci-clear-hub-tt-implementation.patch b/queue-5.3/xhci-fix-use-after-free-regression-in-xhci-clear-hub-tt-implementation.patch new file mode 100644 index 00000000000..bad4db2e5a0 --- /dev/null +++ b/queue-5.3/xhci-fix-use-after-free-regression-in-xhci-clear-hub-tt-implementation.patch @@ -0,0 +1,124 @@ +From 18b74067ac78a2dea65783314c13df98a53d071c Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Fri, 25 Oct 2019 17:30:27 +0300 +Subject: xhci: Fix use-after-free regression in xhci clear hub TT implementation + +From: Mathias Nyman + +commit 18b74067ac78a2dea65783314c13df98a53d071c upstream. + +commit ef513be0a905 ("usb: xhci: Add Clear_TT_Buffer") schedules work +to clear TT buffer, but causes a use-after-free regression at the same time + +Make sure hub_tt_work finishes before endpoint is disabled, otherwise +the work will dereference already freed endpoint and device related +pointers. + +This was triggered when usb core failed to read the configuration +descriptor of a FS/LS device during enumeration. +xhci driver queued clear_tt_work while usb core freed and reallocated +a new device for the next enumeration attempt. + +EHCI driver implents ehci_endpoint_disable() that makes sure +clear_tt_work has finished before it returns, but xhci lacks this support. +usb core will call hcd->driver->endpoint_disable() callback before +disabling endpoints, so we want this in xhci as well. + +The added xhci_endpoint_disable() is based on ehci_endpoint_disable() + +Fixes: ef513be0a905 ("usb: xhci: Add Clear_TT_Buffer") +Cc: # v5.3 +Reported-by: Johan Hovold +Suggested-by: Johan Hovold +Reviewed-by: Johan Hovold +Tested-by: Johan Hovold +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/1572013829-14044-2-git-send-email-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.c | 54 ++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 45 insertions(+), 9 deletions(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -3071,6 +3071,48 @@ void xhci_cleanup_stalled_ring(struct xh + } + } + ++static void xhci_endpoint_disable(struct usb_hcd *hcd, ++ struct usb_host_endpoint *host_ep) ++{ ++ struct xhci_hcd *xhci; ++ struct xhci_virt_device *vdev; ++ struct xhci_virt_ep *ep; ++ struct usb_device *udev; ++ unsigned long flags; ++ unsigned int ep_index; ++ ++ xhci = hcd_to_xhci(hcd); ++rescan: ++ spin_lock_irqsave(&xhci->lock, flags); ++ ++ udev = (struct usb_device *)host_ep->hcpriv; ++ if (!udev || !udev->slot_id) ++ goto done; ++ ++ vdev = xhci->devs[udev->slot_id]; ++ if (!vdev) ++ goto done; ++ ++ ep_index = xhci_get_endpoint_index(&host_ep->desc); ++ ep = &vdev->eps[ep_index]; ++ if (!ep) ++ goto done; ++ ++ /* wait for hub_tt_work to finish clearing hub TT */ ++ if (ep->ep_state & EP_CLEARING_TT) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ schedule_timeout_uninterruptible(1); ++ goto rescan; ++ } ++ ++ if (ep->ep_state) ++ xhci_dbg(xhci, "endpoint disable with ep_state 0x%x\n", ++ ep->ep_state); ++done: ++ host_ep->hcpriv = NULL; ++ spin_unlock_irqrestore(&xhci->lock, flags); ++} ++ + /* + * Called after usb core issues a clear halt control message. + * The host side of the halt should already be cleared by a reset endpoint +@@ -5237,20 +5279,13 @@ static void xhci_clear_tt_buffer_complet + unsigned int ep_index; + unsigned long flags; + +- /* +- * udev might be NULL if tt buffer is cleared during a failed device +- * enumeration due to a halted control endpoint. Usb core might +- * have allocated a new udev for the next enumeration attempt. +- */ +- + xhci = hcd_to_xhci(hcd); ++ ++ spin_lock_irqsave(&xhci->lock, flags); + udev = (struct usb_device *)ep->hcpriv; +- if (!udev) +- return; + slot_id = udev->slot_id; + ep_index = xhci_get_endpoint_index(&ep->desc); + +- spin_lock_irqsave(&xhci->lock, flags); + xhci->devs[slot_id]->eps[ep_index].ep_state &= ~EP_CLEARING_TT; + xhci_ring_doorbell_for_active_rings(xhci, slot_id, ep_index); + spin_unlock_irqrestore(&xhci->lock, flags); +@@ -5287,6 +5322,7 @@ static const struct hc_driver xhci_hc_dr + .free_streams = xhci_free_streams, + .add_endpoint = xhci_add_endpoint, + .drop_endpoint = xhci_drop_endpoint, ++ .endpoint_disable = xhci_endpoint_disable, + .endpoint_reset = xhci_endpoint_reset, + .check_bandwidth = xhci_check_bandwidth, + .reset_bandwidth = xhci_reset_bandwidth, -- 2.47.2