]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.3-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Nov 2019 09:08:56 +0000 (10:08 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Nov 2019 09:08:56 +0000 (10:08 +0100)
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

15 files changed:
queue-5.3/hid-fix-assumption-that-devices-have-inputs.patch [new file with mode: 0644]
queue-5.3/hid-fix-error-message-in-hid_open_report.patch [new file with mode: 0644]
queue-5.3/hid-i2c-hid-add-trekstor-primebook-c11b-to-descriptor-override.patch [new file with mode: 0644]
queue-5.3/scsi-qla2xxx-fix-partial-flash-write-of-mbi.patch [new file with mode: 0644]
queue-5.3/scsi-target-cxgbit-fix-cxgbit_fw4_ack.patch [new file with mode: 0644]
queue-5.3/series
queue-5.3/usb-gadget-reject-endpoints-with-0-maxpacket-value.patch [new file with mode: 0644]
queue-5.3/usb-ldusb-fix-control-message-timeout.patch [new file with mode: 0644]
queue-5.3/usb-ldusb-fix-ring-buffer-locking.patch [new file with mode: 0644]
queue-5.3/usb-serial-whiteheat-fix-line-speed-endianness.patch [new file with mode: 0644]
queue-5.3/usb-serial-whiteheat-fix-potential-slab-corruption.patch [new file with mode: 0644]
queue-5.3/usb-storage-revert-commit-747668dbc061-usb-storage-set-virt_boundary_mask-to-avoid-sg-overflows.patch [new file with mode: 0644]
queue-5.3/usb-xhci-fix-__le32-__le64-accessors-in-debugfs-code.patch [new file with mode: 0644]
queue-5.3/usb-xhci-fix-immediate-data-transfer-endianness.patch [new file with mode: 0644]
queue-5.3/xhci-fix-use-after-free-regression-in-xhci-clear-hub-tt-implementation.patch [new file with mode: 0644]

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 (file)
index 0000000..249fe44
--- /dev/null
@@ -0,0 +1,384 @@
+From d9d4b1e46d9543a82c23f6df03f4ad697dab361b Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Thu, 3 Oct 2019 14:53:59 -0400
+Subject: HID: Fix assumption that devices have inputs
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+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 <stern@rowland.harvard.edu>
+CC: <stable@vger.kernel.org>
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..081c260
--- /dev/null
@@ -0,0 +1,60 @@
+From b3a81c777dcb093020680490ab970d85e2f6f04f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= <mirq-linux@rere.qmqm.pl>
+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 <mirq-linux@rere.qmqm.pl>
+
+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 <mirq-linux@rere.qmqm.pl>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..a16d617
--- /dev/null
@@ -0,0 +1,50 @@
+From 09f3dbe474735df13dd8a66d3d1231048d9b373f Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Mon, 7 Oct 2019 20:56:26 +0200
+Subject: HID: i2c-hid: add Trekstor Primebook C11B to descriptor override
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+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 <hdegoede@redhat.com>
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..ef403e1
--- /dev/null
@@ -0,0 +1,50 @@
+From 8d8b83f5be2a3bdac3695a94e6cb5e50bd114869 Mon Sep 17 00:00:00 2001
+From: Quinn Tran <qutran@marvell.com>
+Date: Tue, 22 Oct 2019 12:36:43 -0700
+Subject: scsi: qla2xxx: Fix partial flash write of MBI
+
+From: Quinn Tran <qutran@marvell.com>
+
+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 <qutran@marvell.com>
+Signed-off-by: Girish Basrur <gbasrur@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..a318a82
--- /dev/null
@@ -0,0 +1,44 @@
+From fc5b220b2dcf8b512d9bd46fd17f82257e49bf89 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bvanassche@acm.org>
+Date: Wed, 23 Oct 2019 13:21:50 -0700
+Subject: scsi: target: cxgbit: Fix cxgbit_fw4_ack()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+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 <varun@chelsio.com>
+Cc: Nicholas Bellinger <nab@linux-iscsi.org>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20191023202150.22173-1-bvanassche@acm.org
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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,
index d82bad0bff18da049de92ac1da7beb9441e5296f..4a8b9ab1179e27cad002d7e25200df275f2d7cd7 100644 (file)
@@ -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 (file)
index 0000000..bbe1196
--- /dev/null
@@ -0,0 +1,56 @@
+From 54f83b8c8ea9b22082a496deadf90447a326954e Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Mon, 28 Oct 2019 10:54:26 -0400
+Subject: USB: gadget: Reject endpoints with 0 maxpacket value
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+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 <stern@rowland.harvard.edu>
+Reported-and-tested-by: syzbot+8ab8bf161038a8768553@syzkaller.appspotmail.com
+CC: <stable@vger.kernel.org>
+Acked-by: Felipe Balbi <balbi@kernel.org>
+Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1910281052370.1485-100000@iolanthe.rowland.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..0ad54c4
--- /dev/null
@@ -0,0 +1,34 @@
+From 52403cfbc635d28195167618690595013776ebde Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 22 Oct 2019 17:31:27 +0200
+Subject: USB: ldusb: fix control-message timeout
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <stable@vger.kernel.org>     # 2.6.13
+Reported-by: syzbot+a4fbb3bb76cda0ea4e58@syzkaller.appspotmail.com
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191022153127.22295-1-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..f6605be
--- /dev/null
@@ -0,0 +1,48 @@
+From d98ee2a19c3334e9343df3ce254b496f1fc428eb Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 22 Oct 2019 16:32:02 +0200
+Subject: USB: ldusb: fix ring-buffer locking
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <stable@vger.kernel.org>     # 2.6.13
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191022143203.5260-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..60cfe6b
--- /dev/null
@@ -0,0 +1,63 @@
+From 84968291d7924261c6a0624b9a72f952398e258b Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 29 Oct 2019 11:23:54 +0100
+Subject: USB: serial: whiteheat: fix line-speed endianness
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <johan@kernel.org>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20191029102354.2733-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..6c6106f
--- /dev/null
@@ -0,0 +1,35 @@
+From 1251dab9e0a2c4d0d2d48370ba5baa095a5e8774 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Tue, 29 Oct 2019 11:23:53 +0100
+Subject: USB: serial: whiteheat: fix potential slab corruption
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20191029102354.2733-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..aa2cc12
--- /dev/null
@@ -0,0 +1,84 @@
+From 9a976949613132977098fc49510b46fa8678d864 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+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 <stern@rowland.harvard.edu>
+
+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 <piergiorgio.sartor@nexgo.de>
+Link: https://marc.info/?l=linux-usb&m=157134199501202&w=2
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: Seth Bollinger <Seth.Bollinger@digi.com>
+CC: <stable@vger.kernel.org>
+Fixes: 747668dbc061 ("usb-storage: Set virt_boundary_mask to avoid SG overflows")
+Acked-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1910211145520.1673-100000@iolanthe.rowland.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..15622f6
--- /dev/null
@@ -0,0 +1,80 @@
+From d5501d5c29a2e684640507cfee428178d6fd82ca Mon Sep 17 00:00:00 2001
+From: "Ben Dooks (Codethink)" <ben.dooks@codethink.co.uk>
+Date: Fri, 25 Oct 2019 17:30:29 +0300
+Subject: usb: xhci: fix __le32/__le64 accessors in debugfs code
+
+From: Ben Dooks (Codethink) <ben.dooks@codethink.co.uk>
+
+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: <stable@vger.kernel.org> # 4.15+
+Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1572013829-14044-4-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..affe23c
--- /dev/null
@@ -0,0 +1,49 @@
+From bfa3dbb343f664573292afb9e44f9abeb81a19de Mon Sep 17 00:00:00 2001
+From: Samuel Holland <samuel@sholland.org>
+Date: Fri, 25 Oct 2019 17:30:28 +0300
+Subject: usb: xhci: fix Immediate Data Transfer endianness
+
+From: Samuel Holland <samuel@sholland.org>
+
+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: <stable@vger.kernel.org> # 5.2+
+Fixes: 33e39350ebd2 ("usb: xhci: add Immediate Data Transfer support")
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1572013829-14044-3-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..bad4db2
--- /dev/null
@@ -0,0 +1,124 @@
+From 18b74067ac78a2dea65783314c13df98a53d071c Mon Sep 17 00:00:00 2001
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+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 <mathias.nyman@linux.intel.com>
+
+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: <stable@vger.kernel.org> # v5.3
+Reported-by: Johan Hovold <johan@kernel.org>
+Suggested-by: Johan Hovold <johan@kernel.org>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Tested-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/1572013829-14044-2-git-send-email-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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,