--- /dev/null
+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-sony.c | 12 +++++++++---
+ drivers/hid/hid-tmff.c | 12 +++++++++---
+ drivers/hid/hid-zpff.c | 12 +++++++++---
+ 12 files changed, 108 insertions(+), 32 deletions(-)
+
+--- a/drivers/hid/hid-axff.c
++++ b/drivers/hid/hid-axff.c
+@@ -75,13 +75,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
+@@ -87,13 +87,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
+@@ -59,13 +59,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
+@@ -77,14 +77,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
+@@ -140,13 +140,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
+@@ -62,11 +62,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
+@@ -129,12 +129,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
+@@ -1158,8 +1158,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);
+@@ -1171,6 +1171,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
+@@ -127,12 +127,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-sony.c
++++ b/drivers/hid/hid-sony.c
+@@ -1960,9 +1960,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
+@@ -136,12 +136,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
+@@ -66,11 +66,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)
--- /dev/null
+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
+@@ -681,6 +681,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;
+
+@@ -741,11 +742,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
+@@ -91,7 +91,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) */