--- /dev/null
+From 3e4f8e21c4f27bcf30a48486b9dcc269512b79ff Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 19 Dec 2019 17:10:16 +0100
+Subject: USB: core: fix check for duplicate endpoints
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 3e4f8e21c4f27bcf30a48486b9dcc269512b79ff upstream.
+
+Amend the endpoint-descriptor sanity checks to detect all duplicate
+endpoint addresses in a configuration.
+
+Commit 0a8fd1346254 ("USB: fix problems with duplicate endpoint
+addresses") added a check for duplicate endpoint addresses within a
+single alternate setting, but did not look for duplicate addresses in
+other interfaces.
+
+The current check would also not detect all duplicate addresses when one
+endpoint is as a (bi-directional) control endpoint.
+
+This specifically avoids overwriting the endpoint entries in struct
+usb_device when enabling a duplicate endpoint, something which could
+potentially lead to crashes or leaks, for example, when endpoints are
+later disabled.
+
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20191219161016.6695-1-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/config.c | 70 ++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 58 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -203,9 +203,58 @@ static const unsigned short super_speed_
+ [USB_ENDPOINT_XFER_INT] = 1024,
+ };
+
+-static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
+- int asnum, struct usb_host_interface *ifp, int num_ep,
+- unsigned char *buffer, int size)
++static bool endpoint_is_duplicate(struct usb_endpoint_descriptor *e1,
++ struct usb_endpoint_descriptor *e2)
++{
++ if (e1->bEndpointAddress == e2->bEndpointAddress)
++ return true;
++
++ if (usb_endpoint_xfer_control(e1) || usb_endpoint_xfer_control(e2)) {
++ if (usb_endpoint_num(e1) == usb_endpoint_num(e2))
++ return true;
++ }
++
++ return false;
++}
++
++/*
++ * Check for duplicate endpoint addresses in other interfaces and in the
++ * altsetting currently being parsed.
++ */
++static bool config_endpoint_is_duplicate(struct usb_host_config *config,
++ int inum, int asnum, struct usb_endpoint_descriptor *d)
++{
++ struct usb_endpoint_descriptor *epd;
++ struct usb_interface_cache *intfc;
++ struct usb_host_interface *alt;
++ int i, j, k;
++
++ for (i = 0; i < config->desc.bNumInterfaces; ++i) {
++ intfc = config->intf_cache[i];
++
++ for (j = 0; j < intfc->num_altsetting; ++j) {
++ alt = &intfc->altsetting[j];
++
++ if (alt->desc.bInterfaceNumber == inum &&
++ alt->desc.bAlternateSetting != asnum)
++ continue;
++
++ for (k = 0; k < alt->desc.bNumEndpoints; ++k) {
++ epd = &alt->endpoint[k].desc;
++
++ if (endpoint_is_duplicate(epd, d))
++ return true;
++ }
++ }
++ }
++
++ return false;
++}
++
++static int usb_parse_endpoint(struct device *ddev, int cfgno,
++ struct usb_host_config *config, int inum, int asnum,
++ struct usb_host_interface *ifp, int num_ep,
++ unsigned char *buffer, int size)
+ {
+ unsigned char *buffer0 = buffer;
+ struct usb_endpoint_descriptor *d;
+@@ -242,13 +291,10 @@ static int usb_parse_endpoint(struct dev
+ goto skip_to_next_endpoint_or_interface_descriptor;
+
+ /* Check for duplicate endpoint addresses */
+- for (i = 0; i < ifp->desc.bNumEndpoints; ++i) {
+- if (ifp->endpoint[i].desc.bEndpointAddress ==
+- d->bEndpointAddress) {
+- dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n",
+- cfgno, inum, asnum, d->bEndpointAddress);
+- goto skip_to_next_endpoint_or_interface_descriptor;
+- }
++ if (config_endpoint_is_duplicate(config, inum, asnum, d)) {
++ dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n",
++ cfgno, inum, asnum, d->bEndpointAddress);
++ goto skip_to_next_endpoint_or_interface_descriptor;
+ }
+
+ endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints];
+@@ -522,8 +568,8 @@ static int usb_parse_interface(struct de
+ if (((struct usb_descriptor_header *) buffer)->bDescriptorType
+ == USB_DT_INTERFACE)
+ break;
+- retval = usb_parse_endpoint(ddev, cfgno, inum, asnum, alt,
+- num_ep, buffer, size);
++ retval = usb_parse_endpoint(ddev, cfgno, config, inum, asnum,
++ alt, num_ep, buffer, size);
+ if (retval < 0)
+ return retval;
+ ++n;
--- /dev/null
+From 0d3010fa442429f8780976758719af05592ff19f Mon Sep 17 00:00:00 2001
+From: Daniele Palmas <dnlplm@gmail.com>
+Date: Fri, 13 Dec 2019 14:56:15 +0100
+Subject: USB: serial: option: add Telit ME910G1 0x110a composition
+
+From: Daniele Palmas <dnlplm@gmail.com>
+
+commit 0d3010fa442429f8780976758719af05592ff19f upstream.
+
+This patch adds the following Telit ME910G1 composition:
+
+0x110a: tty, tty, tty, rmnet
+
+Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/option.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -1175,6 +1175,8 @@ static const struct usb_device_id option
+ .driver_info = NCTRL(0) | RSVD(3) },
+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1102, 0xff), /* Telit ME910 (ECM) */
+ .driver_info = NCTRL(0) },
++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x110a, 0xff), /* Telit ME910G1 */
++ .driver_info = NCTRL(0) | RSVD(3) },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
+ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),