From: Greg Kroah-Hartman Date: Fri, 20 Apr 2018 08:29:00 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v3.18.106~63 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c922598cfcbc8b4140f2c2219b5efd09e175e5cd;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: acpi-hotplug-pci-check-presence-of-slot-itself-in-get_slot_status.patch acpi-video-add-quirk-to-force-acpi-video-backlight-on-samsung-670z5e.patch hid-i2c-hid-fix-size-check-and-type-usage.patch i2c-i801-restore-configuration-at-shutdown.patch regmap-fix-reversed-bounds-check-in-regmap_raw_write.patch smb3-fix-root-directory-when-server-returns-inode-number-of-zero.patch usb-dwc3-pci-properly-cleanup-resource.patch usb-fix-usb3-devices-behind-usb3-hubs-not-resuming-at-hibernate-thaw.patch usb-gadget-f_midi-fixing-a-possible-double-free-in-f_midi.patch --- diff --git a/queue-4.9/acpi-hotplug-pci-check-presence-of-slot-itself-in-get_slot_status.patch b/queue-4.9/acpi-hotplug-pci-check-presence-of-slot-itself-in-get_slot_status.patch new file mode 100644 index 00000000000..5b2ae93b93c --- /dev/null +++ b/queue-4.9/acpi-hotplug-pci-check-presence-of-slot-itself-in-get_slot_status.patch @@ -0,0 +1,107 @@ +From 13d3047c81505cc0fb9bdae7810676e70523c8bf Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Mon, 12 Feb 2018 13:55:23 +0300 +Subject: ACPI / hotplug / PCI: Check presence of slot itself in get_slot_status() + +From: Mika Westerberg + +commit 13d3047c81505cc0fb9bdae7810676e70523c8bf upstream. + +Mike Lothian reported that plugging in a USB-C device does not work +properly in his Dell Alienware system. This system has an Intel Alpine +Ridge Thunderbolt controller providing USB-C functionality. In these +systems the USB controller (xHCI) is hotplugged whenever a device is +connected to the port using ACPI-based hotplug. + +The ACPI description of the root port in question is as follows: + + Device (RP01) + { + Name (_ADR, 0x001C0000) + + Device (PXSX) + { + Name (_ADR, 0x02) + + Method (_RMV, 0, NotSerialized) + { + // ... + } + } + +Here _ADR 0x02 means device 0, function 2 on the bus under root port (RP01) +but that seems to be incorrect because device 0 is the upstream port of the +Alpine Ridge PCIe switch and it has no functions other than 0 (the bridge +itself). When we get ACPI Notify() to the root port resulting from +connecting a USB-C device, Linux tries to read PCI_VENDOR_ID from device 0, +function 2 which of course always returns 0xffffffff because there is no +such function and we never find the device. + +In Windows this works fine. + +Now, since we get ACPI Notify() to the root port and not to the PXSX device +we should actually start our scan from there as well and not from the +non-existent PXSX device. Fix this by checking presence of the slot itself +(function 0) if we fail to do that otherwise. + +While there use pci_bus_read_dev_vendor_id() in get_slot_status(), which is +the recommended way to read Device and Vendor IDs of devices on PCI buses. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=198557 +Reported-by: Mike Lothian +Signed-off-by: Mika Westerberg +Signed-off-by: Bjorn Helgaas +Reviewed-by: Rafael J. Wysocki +Cc: Greg Kroah-Hartman +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/hotplug/acpiphp_glue.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +--- a/drivers/pci/hotplug/acpiphp_glue.c ++++ b/drivers/pci/hotplug/acpiphp_glue.c +@@ -587,6 +587,7 @@ static unsigned int get_slot_status(stru + { + unsigned long long sta = 0; + struct acpiphp_func *func; ++ u32 dvid; + + list_for_each_entry(func, &slot->funcs, sibling) { + if (func->flags & FUNC_HAS_STA) { +@@ -597,19 +598,27 @@ static unsigned int get_slot_status(stru + if (ACPI_SUCCESS(status) && sta) + break; + } else { +- u32 dvid; +- +- pci_bus_read_config_dword(slot->bus, +- PCI_DEVFN(slot->device, +- func->function), +- PCI_VENDOR_ID, &dvid); +- if (dvid != 0xffffffff) { ++ if (pci_bus_read_dev_vendor_id(slot->bus, ++ PCI_DEVFN(slot->device, func->function), ++ &dvid, 0)) { + sta = ACPI_STA_ALL; + break; + } + } + } + ++ if (!sta) { ++ /* ++ * Check for the slot itself since it may be that the ++ * ACPI slot is a device below PCIe upstream port so in ++ * that case it may not even be reachable yet. ++ */ ++ if (pci_bus_read_dev_vendor_id(slot->bus, ++ PCI_DEVFN(slot->device, 0), &dvid, 0)) { ++ sta = ACPI_STA_ALL; ++ } ++ } ++ + return (unsigned int)sta; + } + diff --git a/queue-4.9/acpi-video-add-quirk-to-force-acpi-video-backlight-on-samsung-670z5e.patch b/queue-4.9/acpi-video-add-quirk-to-force-acpi-video-backlight-on-samsung-670z5e.patch new file mode 100644 index 00000000000..358d55557bf --- /dev/null +++ b/queue-4.9/acpi-video-add-quirk-to-force-acpi-video-backlight-on-samsung-670z5e.patch @@ -0,0 +1,41 @@ +From bbf038618a24d72e2efc19146ef421bb1e1eda1a Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 19 Mar 2018 18:01:45 +0100 +Subject: ACPI / video: Add quirk to force acpi-video backlight on Samsung 670Z5E + +From: Hans de Goede + +commit bbf038618a24d72e2efc19146ef421bb1e1eda1a upstream. + +Just like many other Samsung models, the 670Z5E needs to use the acpi-video +backlight interface rather then the native one for backlight control to +work, add a quirk for this. + +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1557060 +Cc: All applicable +Signed-off-by: Hans de Goede +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/video_detect.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/acpi/video_detect.c ++++ b/drivers/acpi/video_detect.c +@@ -214,6 +214,15 @@ static const struct dmi_system_id video_ + }, + }, + { ++ /* https://bugzilla.redhat.com/show_bug.cgi?id=1557060 */ ++ .callback = video_detect_force_video, ++ .ident = "SAMSUNG 670Z5E", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "670Z5E"), ++ }, ++ }, ++ { + /* https://bugzilla.redhat.com/show_bug.cgi?id=1094948 */ + .callback = video_detect_force_video, + .ident = "SAMSUNG 730U3E/740U3E", diff --git a/queue-4.9/hid-i2c-hid-fix-size-check-and-type-usage.patch b/queue-4.9/hid-i2c-hid-fix-size-check-and-type-usage.patch new file mode 100644 index 00000000000..1e4ad8eafa5 --- /dev/null +++ b/queue-4.9/hid-i2c-hid-fix-size-check-and-type-usage.patch @@ -0,0 +1,59 @@ +From ac75a041048b8c1f7418e27621ca5efda8571043 Mon Sep 17 00:00:00 2001 +From: Aaron Ma +Date: Mon, 8 Jan 2018 10:41:40 +0800 +Subject: HID: i2c-hid: fix size check and type usage + +From: Aaron Ma + +commit ac75a041048b8c1f7418e27621ca5efda8571043 upstream. + +When convert char array with signed int, if the inbuf[x] is negative then +upper bits will be set to 1. Fix this by using u8 instead of char. + +ret_size has to be at least 3, hid_input_report use it after minus 2 bytes. + +Cc: stable@vger.kernel.org +Signed-off-by: Aaron Ma +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/i2c-hid/i2c-hid.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/drivers/hid/i2c-hid/i2c-hid.c ++++ b/drivers/hid/i2c-hid/i2c-hid.c +@@ -142,10 +142,10 @@ struct i2c_hid { + * register of the HID + * descriptor. */ + unsigned int bufsize; /* i2c buffer size */ +- char *inbuf; /* Input buffer */ +- char *rawbuf; /* Raw Input buffer */ +- char *cmdbuf; /* Command buffer */ +- char *argsbuf; /* Command arguments buffer */ ++ u8 *inbuf; /* Input buffer */ ++ u8 *rawbuf; /* Raw Input buffer */ ++ u8 *cmdbuf; /* Command buffer */ ++ u8 *argsbuf; /* Command arguments buffer */ + + unsigned long flags; /* device flags */ + unsigned long quirks; /* Various quirks */ +@@ -451,7 +451,8 @@ out_unlock: + + static void i2c_hid_get_input(struct i2c_hid *ihid) + { +- int ret, ret_size; ++ int ret; ++ u32 ret_size; + int size = le16_to_cpu(ihid->hdesc.wMaxInputLength); + + if (size > ihid->bufsize) +@@ -476,7 +477,7 @@ static void i2c_hid_get_input(struct i2c + return; + } + +- if (ret_size > size) { ++ if ((ret_size > size) || (ret_size <= 2)) { + dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", + __func__, size, ret_size); + return; diff --git a/queue-4.9/i2c-i801-restore-configuration-at-shutdown.patch b/queue-4.9/i2c-i801-restore-configuration-at-shutdown.patch new file mode 100644 index 00000000000..b9f540ea410 --- /dev/null +++ b/queue-4.9/i2c-i801-restore-configuration-at-shutdown.patch @@ -0,0 +1,50 @@ +From f7f6d915a10f7f2bce17e3b1b7d3376562395a28 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Wed, 11 Apr 2018 18:05:34 +0200 +Subject: i2c: i801: Restore configuration at shutdown + +From: Jean Delvare + +commit f7f6d915a10f7f2bce17e3b1b7d3376562395a28 upstream. + +On some systems, the BIOS expects certain SMBus register values to +match the hardware defaults. Restore these configuration registers at +shutdown time to avoid confusing the BIOS. This avoids hard-locking +such systems upon reboot. + +Signed-off-by: Jean Delvare +Tested-by: Jason Andryuk +Signed-off-by: Wolfram Sang +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-i801.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/i2c/busses/i2c-i801.c ++++ b/drivers/i2c/busses/i2c-i801.c +@@ -1679,6 +1679,15 @@ static void i801_remove(struct pci_dev * + */ + } + ++static void i801_shutdown(struct pci_dev *dev) ++{ ++ struct i801_priv *priv = pci_get_drvdata(dev); ++ ++ /* Restore config registers to avoid hard hang on some systems */ ++ i801_disable_host_notify(priv); ++ pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg); ++} ++ + #ifdef CONFIG_PM + static int i801_suspend(struct device *dev) + { +@@ -1711,6 +1720,7 @@ static struct pci_driver i801_driver = { + .id_table = i801_ids, + .probe = i801_probe, + .remove = i801_remove, ++ .shutdown = i801_shutdown, + .driver = { + .pm = &i801_pm_ops, + }, diff --git a/queue-4.9/regmap-fix-reversed-bounds-check-in-regmap_raw_write.patch b/queue-4.9/regmap-fix-reversed-bounds-check-in-regmap_raw_write.patch new file mode 100644 index 00000000000..415f49bdd68 --- /dev/null +++ b/queue-4.9/regmap-fix-reversed-bounds-check-in-regmap_raw_write.patch @@ -0,0 +1,39 @@ +From f00e71091ab92eba52122332586c6ecaa9cd1a56 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 8 Feb 2018 10:23:44 +0300 +Subject: regmap: Fix reversed bounds check in regmap_raw_write() + +From: Dan Carpenter + +commit f00e71091ab92eba52122332586c6ecaa9cd1a56 upstream. + +We're supposed to be checking that "val_len" is not too large but +instead we check if it is smaller than the max. + +The only function affected would be regmap_i2c_smbus_i2c_write() in +drivers/base/regmap/regmap-i2c.c. Strangely that function has its own +limit check which returns an error if (count >= I2C_SMBUS_BLOCK_MAX) so +it doesn't look like it has ever been able to do anything except return +an error. + +Fixes: c335931ed9d2 ("regmap: Add raw_write/read checks for max_raw_write/read sizes") +Signed-off-by: Dan Carpenter +Signed-off-by: Mark Brown +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/regmap/regmap.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/base/regmap/regmap.c ++++ b/drivers/base/regmap/regmap.c +@@ -1736,7 +1736,7 @@ int regmap_raw_write(struct regmap *map, + return -EINVAL; + if (val_len % map->format.val_bytes) + return -EINVAL; +- if (map->max_raw_write && map->max_raw_write > val_len) ++ if (map->max_raw_write && map->max_raw_write < val_len) + return -E2BIG; + + map->lock(map->lock_arg); diff --git a/queue-4.9/series b/queue-4.9/series index 6a6b86465ac..3aee7d69537 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -14,3 +14,12 @@ arm-dts-exynos-fix-iommu-support-for-gscaler-devices-on-exynos5250.patch arm-dts-at91-sama5d4-fix-pinctrl-compatible-string.patch spi-fix-scatterlist-elements-size-in-spi_map_buf.patch xen-netfront-fix-hang-on-device-removal.patch +regmap-fix-reversed-bounds-check-in-regmap_raw_write.patch +acpi-video-add-quirk-to-force-acpi-video-backlight-on-samsung-670z5e.patch +acpi-hotplug-pci-check-presence-of-slot-itself-in-get_slot_status.patch +usb-gadget-f_midi-fixing-a-possible-double-free-in-f_midi.patch +usb-fix-usb3-devices-behind-usb3-hubs-not-resuming-at-hibernate-thaw.patch +usb-dwc3-pci-properly-cleanup-resource.patch +smb3-fix-root-directory-when-server-returns-inode-number-of-zero.patch +hid-i2c-hid-fix-size-check-and-type-usage.patch +i2c-i801-restore-configuration-at-shutdown.patch diff --git a/queue-4.9/smb3-fix-root-directory-when-server-returns-inode-number-of-zero.patch b/queue-4.9/smb3-fix-root-directory-when-server-returns-inode-number-of-zero.patch new file mode 100644 index 00000000000..0401b4c122a --- /dev/null +++ b/queue-4.9/smb3-fix-root-directory-when-server-returns-inode-number-of-zero.patch @@ -0,0 +1,98 @@ +From 7ea884c77e5c97f1e0a1a422d961d27f78ca2745 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Sat, 31 Mar 2018 18:13:38 -0500 +Subject: smb3: Fix root directory when server returns inode number of zero + +From: Steve French + +commit 7ea884c77e5c97f1e0a1a422d961d27f78ca2745 upstream. + +Some servers return inode number zero for the root directory, which +causes ls to display incorrect data (missing "." and ".."). + +If the server returns zero for the inode number of the root directory, +fake an inode number for it. + +Signed-off-by: Steve French +Reviewed-by: Pavel Shilovsky +CC: Stable +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifsglob.h | 1 + + fs/cifs/inode.c | 33 +++++++++++++++++++++++++++++++++ + 2 files changed, 34 insertions(+) + +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -1412,6 +1412,7 @@ struct dfs_info3_param { + #define CIFS_FATTR_NEED_REVAL 0x4 + #define CIFS_FATTR_INO_COLLISION 0x8 + #define CIFS_FATTR_UNKNOWN_NLINK 0x10 ++#define CIFS_FATTR_FAKE_ROOT_INO 0x20 + + struct cifs_fattr { + u32 cf_flags; +--- a/fs/cifs/inode.c ++++ b/fs/cifs/inode.c +@@ -701,6 +701,18 @@ cgfi_exit: + return rc; + } + ++/* Simple function to return a 64 bit hash of string. Rarely called */ ++static __u64 simple_hashstr(const char *str) ++{ ++ const __u64 hash_mult = 1125899906842597L; /* a big enough prime */ ++ __u64 hash = 0; ++ ++ while (*str) ++ hash = (hash + (__u64) *str++) * hash_mult; ++ ++ return hash; ++} ++ + int + cifs_get_inode_info(struct inode **inode, const char *full_path, + FILE_ALL_INFO *data, struct super_block *sb, int xid, +@@ -810,6 +822,14 @@ cifs_get_inode_info(struct inode **inode + tmprc); + fattr.cf_uniqueid = iunique(sb, ROOT_I); + cifs_autodisable_serverino(cifs_sb); ++ } else if ((fattr.cf_uniqueid == 0) && ++ strlen(full_path) == 0) { ++ /* some servers ret bad root ino ie 0 */ ++ cifs_dbg(FYI, "Invalid (0) inodenum\n"); ++ fattr.cf_flags |= ++ CIFS_FATTR_FAKE_ROOT_INO; ++ fattr.cf_uniqueid = ++ simple_hashstr(tcon->treeName); + } + } + } else +@@ -826,6 +846,16 @@ cifs_get_inode_info(struct inode **inode + &fattr.cf_uniqueid, data); + if (tmprc) + fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; ++ else if ((fattr.cf_uniqueid == 0) && ++ strlen(full_path) == 0) { ++ /* ++ * Reuse existing root inode num since ++ * inum zero for root causes ls of . and .. to ++ * not be returned ++ */ ++ cifs_dbg(FYI, "Srv ret 0 inode num for root\n"); ++ fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; ++ } + } else + fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid; + } +@@ -887,6 +917,9 @@ cifs_get_inode_info(struct inode **inode + } + + cgii_exit: ++ if ((*inode) && ((*inode)->i_ino == 0)) ++ cifs_dbg(FYI, "inode number of zero returned\n"); ++ + kfree(buf); + cifs_put_tlink(tlink); + return rc; diff --git a/queue-4.9/usb-dwc3-pci-properly-cleanup-resource.patch b/queue-4.9/usb-dwc3-pci-properly-cleanup-resource.patch new file mode 100644 index 00000000000..18be241dee9 --- /dev/null +++ b/queue-4.9/usb-dwc3-pci-properly-cleanup-resource.patch @@ -0,0 +1,33 @@ +From cabdf83dadfb3d83eec31e0f0638a92dbd716435 Mon Sep 17 00:00:00 2001 +From: Thinh Nguyen +Date: Mon, 19 Mar 2018 13:07:35 -0700 +Subject: usb: dwc3: pci: Properly cleanup resource + +From: Thinh Nguyen + +commit cabdf83dadfb3d83eec31e0f0638a92dbd716435 upstream. + +Platform device is allocated before adding resources. Make sure to +properly cleanup on error case. + +Cc: +Fixes: f1c7e7108109 ("usb: dwc3: convert to pcim_enable_device()") +Signed-off-by: Thinh Nguyen +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/dwc3-pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/dwc3/dwc3-pci.c ++++ b/drivers/usb/dwc3/dwc3-pci.c +@@ -173,7 +173,7 @@ static int dwc3_pci_probe(struct pci_dev + ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); + if (ret) { + dev_err(dev, "couldn't add resources to dwc3 device\n"); +- return ret; ++ goto err; + } + + dwc3->dev.parent = dev; diff --git a/queue-4.9/usb-fix-usb3-devices-behind-usb3-hubs-not-resuming-at-hibernate-thaw.patch b/queue-4.9/usb-fix-usb3-devices-behind-usb3-hubs-not-resuming-at-hibernate-thaw.patch new file mode 100644 index 00000000000..92f7304d3fa --- /dev/null +++ b/queue-4.9/usb-fix-usb3-devices-behind-usb3-hubs-not-resuming-at-hibernate-thaw.patch @@ -0,0 +1,60 @@ +From 64627388b50158fd24d6ad88132525b95a5ef573 Mon Sep 17 00:00:00 2001 +From: Zhengjun Xing +Date: Wed, 21 Mar 2018 13:29:42 +0800 +Subject: USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Zhengjun Xing + +commit 64627388b50158fd24d6ad88132525b95a5ef573 upstream. + +USB3 hubs don't support global suspend. + +USB3 specification 10.10, Enhanced SuperSpeed hubs only support selective +suspend and resume, they do not support global suspend/resume where the +hub downstream facing ports states are not affected. + +When system enters hibernation it first enters freeze process where only +the root hub enters suspend, usb_port_suspend() is not called for other +devices, and suspend status flags are not set for them. Other devices are +expected to suspend globally. Some external USB3 hubs will suspend the +downstream facing port at global suspend. These devices won't be resumed +at thaw as the suspend status flag is not set. + +A USB3 removable hard disk connected through a USB3 hub that won't resume +at thaw will fail to synchronize SCSI cache, return “cmd cmplt err -71” +error, and needs a 60 seconds timeout which causing system hang for 60s +before the USB host reset the port for the USB3 removable hard disk to +recover. + +Fix this by always calling usb_port_suspend() during freeze for USB3 +devices. + +Signed-off-by: Zhengjun Xing +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/generic.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/usb/core/generic.c ++++ b/drivers/usb/core/generic.c +@@ -208,8 +208,13 @@ static int generic_suspend(struct usb_de + if (!udev->parent) + rc = hcd_bus_suspend(udev, msg); + +- /* Non-root devices don't need to do anything for FREEZE or PRETHAW */ +- else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) ++ /* ++ * Non-root USB2 devices don't need to do anything for FREEZE ++ * or PRETHAW. USB3 devices don't support global suspend and ++ * needs to be selectively suspended. ++ */ ++ else if ((msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) ++ && (udev->speed < USB_SPEED_SUPER)) + rc = 0; + else + rc = usb_port_suspend(udev, msg); diff --git a/queue-4.9/usb-gadget-f_midi-fixing-a-possible-double-free-in-f_midi.patch b/queue-4.9/usb-gadget-f_midi-fixing-a-possible-double-free-in-f_midi.patch new file mode 100644 index 00000000000..82f9f711130 --- /dev/null +++ b/queue-4.9/usb-gadget-f_midi-fixing-a-possible-double-free-in-f_midi.patch @@ -0,0 +1,68 @@ +From 7fafcfdf6377b18b2a726ea554d6e593ba44349f Mon Sep 17 00:00:00 2001 +From: "Yavuz, Tuba" +Date: Fri, 23 Mar 2018 17:00:38 +0000 +Subject: USB: gadget: f_midi: fixing a possible double-free in f_midi + +From: Yavuz, Tuba + +commit 7fafcfdf6377b18b2a726ea554d6e593ba44349f upstream. + +It looks like there is a possibility of a double-free vulnerability on an +error path of the f_midi_set_alt function in the f_midi driver. If the +path is feasible then free_ep_req gets called twice: + + req->complete = f_midi_complete; + err = usb_ep_queue(midi->out_ep, req, GFP_ATOMIC); + => ... + usb_gadget_giveback_request + => + f_midi_complete (CALLBACK) + (inside f_midi_complete, for various cases of status) + free_ep_req(ep, req); // first kfree + if (err) { + ERROR(midi, "%s: couldn't enqueue request: %d\n", + midi->out_ep->name, err); + free_ep_req(midi->out_ep, req); // second kfree + return err; + } + +The double-free possibility was introduced with commit ad0d1a058eac +("usb: gadget: f_midi: fix leak on failed to enqueue out requests"). + +Found by MOXCAFE tool. + +Signed-off-by: Tuba Yavuz +Fixes: ad0d1a058eac ("usb: gadget: f_midi: fix leak on failed to enqueue out requests") +Acked-by: Felipe Balbi +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/function/f_midi.c | 3 ++- + drivers/usb/gadget/u_f.h | 2 ++ + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/f_midi.c ++++ b/drivers/usb/gadget/function/f_midi.c +@@ -389,7 +389,8 @@ static int f_midi_set_alt(struct usb_fun + if (err) { + ERROR(midi, "%s: couldn't enqueue request: %d\n", + midi->out_ep->name, err); +- free_ep_req(midi->out_ep, req); ++ if (req->buf != NULL) ++ free_ep_req(midi->out_ep, req); + return err; + } + } +--- a/drivers/usb/gadget/u_f.h ++++ b/drivers/usb/gadget/u_f.h +@@ -64,7 +64,9 @@ struct usb_request *alloc_ep_req(struct + /* Frees a usb_request previously allocated by alloc_ep_req() */ + static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req) + { ++ WARN_ON(req->buf == NULL); + kfree(req->buf); ++ req->buf = NULL; + usb_ep_free_request(ep, req); + } +