From: Greg Kroah-Hartman Date: Wed, 26 Feb 2020 09:43:51 +0000 (+0100) Subject: 5.5-stable patches X-Git-Tag: v4.4.215~70 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8fb122e3e215bb09d8bd3cdbd17f7da752773e3d;p=thirdparty%2Fkernel%2Fstable-queue.git 5.5-stable patches added patches: hwmon-acpi_power_meter-fix-lockdep-splat.patch scsi-revert-target-core-inline-transport_lun_remove_cmd.patch staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch staging-rtl8188eu-fix-potential-security-hole.patch staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch staging-rtl8723bs-fix-potential-security-hole.patch usb-core-add-endpoint-blacklist-quirk.patch usb-dwc2-fix-set-clear_feature-and-get_status-flows.patch usb-dwc3-debug-fix-string-position-formatting-mixup-with-ret-and-len.patch usb-dwc3-gadget-check-for-ioc-lst-bit-in-trb-ctrl-fields.patch usb-fix-novation-sourcecontrol-xl-after-suspend.patch usb-hub-don-t-record-a-connect-change-event-during-reset-resume.patch usb-hub-fix-the-broken-detection-of-usb3-device-in-smsc-hub.patch usb-quirks-blacklist-duplicate-ep-on-sound-devices-usbpre2.patch usb-uas-fix-a-plug-unplug-racing.patch --- diff --git a/queue-5.5/hwmon-acpi_power_meter-fix-lockdep-splat.patch b/queue-5.5/hwmon-acpi_power_meter-fix-lockdep-splat.patch new file mode 100644 index 00000000000..b80a0dfd7fb --- /dev/null +++ b/queue-5.5/hwmon-acpi_power_meter-fix-lockdep-splat.patch @@ -0,0 +1,222 @@ +From badcd4546d52ae4318f2bcfda0e47a1394b60e38 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Wed, 19 Feb 2020 14:36:14 -0800 +Subject: hwmon: (acpi_power_meter) Fix lockdep splat + +From: Guenter Roeck + +commit badcd4546d52ae4318f2bcfda0e47a1394b60e38 upstream. + +Damien Le Moal reports a lockdep splat with the acpi_power_meter, +observed with Linux v5.5 and later. + +====================================================== +WARNING: possible circular locking dependency detected +5.6.0-rc2+ #629 Not tainted +------------------------------------------------------ +python/1397 is trying to acquire lock: +ffff888619080070 (&resource->lock){+.+.}, at: show_power+0x3c/0xa0 [acpi_power_meter] + + but task is already holding lock: +ffff88881643f188 (kn->count#119){++++}, at: kernfs_seq_start+0x6a/0x160 + + which lock already depends on the new lock. + + the existing dependency chain (in reverse order) is: + + -> #1 (kn->count#119){++++}: + __kernfs_remove+0x626/0x7e0 + kernfs_remove_by_name_ns+0x41/0x80 + remove_attrs+0xcb/0x3c0 [acpi_power_meter] + acpi_power_meter_notify+0x1f7/0x310 [acpi_power_meter] + acpi_ev_notify_dispatch+0x198/0x1f3 + acpi_os_execute_deferred+0x4d/0x70 + process_one_work+0x7c8/0x1340 + worker_thread+0x94/0xc70 + kthread+0x2ed/0x3f0 + ret_from_fork+0x24/0x30 + + -> #0 (&resource->lock){+.+.}: + __lock_acquire+0x20be/0x49b0 + lock_acquire+0x127/0x340 + __mutex_lock+0x15b/0x1350 + show_power+0x3c/0xa0 [acpi_power_meter] + dev_attr_show+0x3f/0x80 + sysfs_kf_seq_show+0x216/0x410 + seq_read+0x407/0xf90 + vfs_read+0x152/0x2c0 + ksys_read+0xf3/0x1d0 + do_syscall_64+0x95/0x1010 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + + other info that might help us debug this: + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(kn->count#119); + lock(&resource->lock); + lock(kn->count#119); + lock(&resource->lock); + + *** DEADLOCK *** +4 locks held by python/1397: + #0: ffff8890242d64e0 (&f->f_pos_lock){+.+.}, at: __fdget_pos+0x9b/0xb0 + #1: ffff889040be74e0 (&p->lock){+.+.}, at: seq_read+0x6b/0xf90 + #2: ffff8890448eb880 (&of->mutex){+.+.}, at: kernfs_seq_start+0x47/0x160 + #3: ffff88881643f188 (kn->count#119){++++}, at: kernfs_seq_start+0x6a/0x160 + + stack backtrace: +CPU: 10 PID: 1397 Comm: python Not tainted 5.6.0-rc2+ #629 +Hardware name: Supermicro Super Server/X11DPL-i, BIOS 3.1 05/21/2019 +Call Trace: + dump_stack+0x97/0xe0 + check_noncircular+0x32e/0x3e0 + ? print_circular_bug.isra.0+0x1e0/0x1e0 + ? unwind_next_frame+0xb9a/0x1890 + ? entry_SYSCALL_64_after_hwframe+0x49/0xbe + ? graph_lock+0x79/0x170 + ? __lockdep_reset_lock+0x3c0/0x3c0 + ? mark_lock+0xbc/0x1150 + __lock_acquire+0x20be/0x49b0 + ? mark_held_locks+0xe0/0xe0 + ? stack_trace_save+0x91/0xc0 + lock_acquire+0x127/0x340 + ? show_power+0x3c/0xa0 [acpi_power_meter] + ? device_remove_bin_file+0x10/0x10 + ? device_remove_bin_file+0x10/0x10 + __mutex_lock+0x15b/0x1350 + ? show_power+0x3c/0xa0 [acpi_power_meter] + ? show_power+0x3c/0xa0 [acpi_power_meter] + ? mutex_lock_io_nested+0x11f0/0x11f0 + ? lock_downgrade+0x6a0/0x6a0 + ? kernfs_seq_start+0x47/0x160 + ? lock_acquire+0x127/0x340 + ? kernfs_seq_start+0x6a/0x160 + ? device_remove_bin_file+0x10/0x10 + ? show_power+0x3c/0xa0 [acpi_power_meter] + show_power+0x3c/0xa0 [acpi_power_meter] + dev_attr_show+0x3f/0x80 + ? memset+0x20/0x40 + sysfs_kf_seq_show+0x216/0x410 + seq_read+0x407/0xf90 + ? security_file_permission+0x16f/0x2c0 + vfs_read+0x152/0x2c0 + +Problem is that reading an attribute takes the kernfs lock in the kernfs +code, then resource->lock in the driver. During an ACPI notification, the +opposite happens: The resource lock is taken first, followed by the kernfs +lock when sysfs attributes are removed and re-created. Presumably this is +now seen due to some locking related changes in kernfs after v5.4, but it +was likely always a problem. + +Fix the problem by not blindly acquiring the lock in the notification +function. It is only needed to protect the various update functions. +However, those update functions are called anyway when sysfs attributes +are read. This means that we can just stop calling those functions from +the notifier, and the resource lock in the notifier function is no longer +needed. + +That leaves two situations: + +First, METER_NOTIFY_CONFIG removes and re-allocates capability strings. +While it did so under the resource lock, _displaying_ those strings was not +protected, creating a race condition. To solve this problem, selectively +protect both removal/creation and reporting of capability attributes with +the resource lock. + +Second, removing and re-creating the attribute files is no longer protected +by the resource lock. That doesn't matter since access to each individual +attribute is protected by the kernfs lock. Userspace may get messed up if +attributes disappear and reappear under its nose, but that is not different +than today, and there is nothing we can do about it without major driver +restructuring. + +Last but not least, when removing the driver, remove attribute functions +first, then release capability strings. This avoids yet another race +condition. + +Reported-by: Damien Le Moal +Cc: Damien Le Moal +Cc: stable@vger.kernel.org # v5.5+ +Tested-by: Damien Le Moal +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hwmon/acpi_power_meter.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/drivers/hwmon/acpi_power_meter.c ++++ b/drivers/hwmon/acpi_power_meter.c +@@ -355,7 +355,9 @@ static ssize_t show_str(struct device *d + struct acpi_device *acpi_dev = to_acpi_device(dev); + struct acpi_power_meter_resource *resource = acpi_dev->driver_data; + acpi_string val; ++ int ret; + ++ mutex_lock(&resource->lock); + switch (attr->index) { + case 0: + val = resource->model_number; +@@ -372,8 +374,9 @@ static ssize_t show_str(struct device *d + val = ""; + break; + } +- +- return sprintf(buf, "%s\n", val); ++ ret = sprintf(buf, "%s\n", val); ++ mutex_unlock(&resource->lock); ++ return ret; + } + + static ssize_t show_val(struct device *dev, +@@ -817,11 +820,12 @@ static void acpi_power_meter_notify(stru + + resource = acpi_driver_data(device); + +- mutex_lock(&resource->lock); + switch (event) { + case METER_NOTIFY_CONFIG: ++ mutex_lock(&resource->lock); + free_capabilities(resource); + res = read_capabilities(resource); ++ mutex_unlock(&resource->lock); + if (res) + break; + +@@ -830,15 +834,12 @@ static void acpi_power_meter_notify(stru + break; + case METER_NOTIFY_TRIP: + sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME); +- update_meter(resource); + break; + case METER_NOTIFY_CAP: + sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME); +- update_cap(resource); + break; + case METER_NOTIFY_INTERVAL: + sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME); +- update_avg_interval(resource); + break; + case METER_NOTIFY_CAPPING: + sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME); +@@ -848,7 +849,6 @@ static void acpi_power_meter_notify(stru + WARN(1, "Unexpected event %d\n", event); + break; + } +- mutex_unlock(&resource->lock); + + acpi_bus_generate_netlink_event(ACPI_POWER_METER_CLASS, + dev_name(&device->dev), event, 0); +@@ -912,8 +912,8 @@ static int acpi_power_meter_remove(struc + resource = acpi_driver_data(device); + hwmon_device_unregister(resource->hwmon_dev); + +- free_capabilities(resource); + remove_attrs(resource); ++ free_capabilities(resource); + + kfree(resource); + return 0; diff --git a/queue-5.5/scsi-revert-target-core-inline-transport_lun_remove_cmd.patch b/queue-5.5/scsi-revert-target-core-inline-transport_lun_remove_cmd.patch new file mode 100644 index 00000000000..75d1f6847c1 --- /dev/null +++ b/queue-5.5/scsi-revert-target-core-inline-transport_lun_remove_cmd.patch @@ -0,0 +1,148 @@ +From c14335ebb92a98646ddbf447e6cacc66de5269ad Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Sun, 9 Feb 2020 21:12:02 -0800 +Subject: scsi: Revert "target/core: Inline transport_lun_remove_cmd()" + +From: Bart Van Assche + +commit c14335ebb92a98646ddbf447e6cacc66de5269ad upstream. + +Commit 83f85b8ec305 postponed the percpu_ref_put(&se_cmd->se_lun->lun_ref) +call from command completion to the time when the final command reference +is dropped. That approach is not compatible with the iSCSI target driver +because the iSCSI target driver keeps the command with the highest stat_sn +after it has completed until the next command is received (see also +iscsit_ack_from_expstatsn()). Fix this regression by reverting commit +83f85b8ec305. + +Fixes: 83f85b8ec305 ("scsi: target/core: Inline transport_lun_remove_cmd()") +Cc: Pavel Zakharov +Cc: Mike Christie +Cc: +Link: https://lore.kernel.org/r/20200210051202.12934-1-bvanassche@acm.org +Reported-by: Pavel Zakharov +Signed-off-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_transport.c | 31 ++++++++++++++++++++++++++++--- + 1 file changed, 28 insertions(+), 3 deletions(-) + +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -666,6 +666,11 @@ static int transport_cmd_check_stop_to_f + + target_remove_from_state_list(cmd); + ++ /* ++ * Clear struct se_cmd->se_lun before the handoff to FE. ++ */ ++ cmd->se_lun = NULL; ++ + spin_lock_irqsave(&cmd->t_state_lock, flags); + /* + * Determine if frontend context caller is requesting the stopping of +@@ -693,6 +698,17 @@ static int transport_cmd_check_stop_to_f + return cmd->se_tfo->check_stop_free(cmd); + } + ++static void transport_lun_remove_cmd(struct se_cmd *cmd) ++{ ++ struct se_lun *lun = cmd->se_lun; ++ ++ if (!lun) ++ return; ++ ++ if (cmpxchg(&cmd->lun_ref_active, true, false)) ++ percpu_ref_put(&lun->lun_ref); ++} ++ + static void target_complete_failure_work(struct work_struct *work) + { + struct se_cmd *cmd = container_of(work, struct se_cmd, work); +@@ -783,6 +799,8 @@ static void target_handle_abort(struct s + + WARN_ON_ONCE(kref_read(&cmd->cmd_kref) == 0); + ++ transport_lun_remove_cmd(cmd); ++ + transport_cmd_check_stop_to_fabric(cmd); + } + +@@ -1708,6 +1726,7 @@ static void target_complete_tmr_failure( + se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST; + se_cmd->se_tfo->queue_tm_rsp(se_cmd); + ++ transport_lun_remove_cmd(se_cmd); + transport_cmd_check_stop_to_fabric(se_cmd); + } + +@@ -1898,6 +1917,7 @@ void transport_generic_request_failure(s + goto queue_full; + + check_stop: ++ transport_lun_remove_cmd(cmd); + transport_cmd_check_stop_to_fabric(cmd); + return; + +@@ -2195,6 +2215,7 @@ queue_status: + transport_handle_queue_full(cmd, cmd->se_dev, ret, false); + return; + } ++ transport_lun_remove_cmd(cmd); + transport_cmd_check_stop_to_fabric(cmd); + } + +@@ -2289,6 +2310,7 @@ static void target_complete_ok_work(stru + if (ret) + goto queue_full; + ++ transport_lun_remove_cmd(cmd); + transport_cmd_check_stop_to_fabric(cmd); + return; + } +@@ -2314,6 +2336,7 @@ static void target_complete_ok_work(stru + if (ret) + goto queue_full; + ++ transport_lun_remove_cmd(cmd); + transport_cmd_check_stop_to_fabric(cmd); + return; + } +@@ -2349,6 +2372,7 @@ queue_rsp: + if (ret) + goto queue_full; + ++ transport_lun_remove_cmd(cmd); + transport_cmd_check_stop_to_fabric(cmd); + return; + } +@@ -2384,6 +2408,7 @@ queue_status: + break; + } + ++ transport_lun_remove_cmd(cmd); + transport_cmd_check_stop_to_fabric(cmd); + return; + +@@ -2710,6 +2735,9 @@ int transport_generic_free_cmd(struct se + */ + if (cmd->state_active) + target_remove_from_state_list(cmd); ++ ++ if (cmd->se_lun) ++ transport_lun_remove_cmd(cmd); + } + if (aborted) + cmd->free_compl = &compl; +@@ -2781,9 +2809,6 @@ static void target_release_cmd_kref(stru + struct completion *abrt_compl = se_cmd->abrt_compl; + unsigned long flags; + +- if (se_cmd->lun_ref_active) +- percpu_ref_put(&se_cmd->se_lun->lun_ref); +- + if (se_sess) { + spin_lock_irqsave(&se_sess->sess_cmd_lock, flags); + list_del_init(&se_cmd->se_cmd_list); diff --git a/queue-5.5/series b/queue-5.5/series index f7cc223f28e..ddd51cb1075 100644 --- a/queue-5.5/series +++ b/queue-5.5/series @@ -32,3 +32,18 @@ xhci-force-maximum-packet-size-for-full-speed-bulk-devices-to-valid-range.patch xhci-fix-runtime-pm-enabling-for-quirky-intel-hosts.patch xhci-apply-xhci_pme_stuck_quirk-to-intel-comet-lake-platforms.patch xhci-fix-memory-leak-when-caching-protocol-extended-capability-psi-tables-take-2.patch +usb-core-add-endpoint-blacklist-quirk.patch +usb-quirks-blacklist-duplicate-ep-on-sound-devices-usbpre2.patch +usb-uas-fix-a-plug-unplug-racing.patch +usb-fix-novation-sourcecontrol-xl-after-suspend.patch +usb-hub-don-t-record-a-connect-change-event-during-reset-resume.patch +usb-hub-fix-the-broken-detection-of-usb3-device-in-smsc-hub.patch +usb-dwc2-fix-set-clear_feature-and-get_status-flows.patch +usb-dwc3-gadget-check-for-ioc-lst-bit-in-trb-ctrl-fields.patch +usb-dwc3-debug-fix-string-position-formatting-mixup-with-ret-and-len.patch +scsi-revert-target-core-inline-transport_lun_remove_cmd.patch +staging-rtl8188eu-fix-potential-security-hole.patch +staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch +staging-rtl8723bs-fix-potential-security-hole.patch +staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch +hwmon-acpi_power_meter-fix-lockdep-splat.patch diff --git a/queue-5.5/staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch b/queue-5.5/staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch new file mode 100644 index 00000000000..17b799e7b0e --- /dev/null +++ b/queue-5.5/staging-rtl8188eu-fix-potential-overuse-of-kernel-memory.patch @@ -0,0 +1,38 @@ +From 4ddf8ab8d15ddbc52eefb44eb64e38466ce1f70f Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Mon, 10 Feb 2020 12:02:32 -0600 +Subject: staging: rtl8188eu: Fix potential overuse of kernel memory + +From: Larry Finger + +commit 4ddf8ab8d15ddbc52eefb44eb64e38466ce1f70f upstream. + +In routine wpa_supplicant_ioctl(), the user-controlled p->length is +checked to be at least the size of struct ieee_param size, but the code +does not detect the case where p->length is greater than the size +of the struct, thus a malicious user could be wasting kernel memory. +Fixes commit a2c60d42d97c ("Add files for new driver - part 16"). + +Reported by: Pietro Oliva +Cc: Pietro Oliva +Cc: Stable +Fixes commit a2c60d42d97c ("Add files for new driver - part 16"). +Signed-off-by: Larry Finger +Link: https://lore.kernel.org/r/20200210180235.21691-4-Larry.Finger@lwfinger.net +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c ++++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +@@ -2011,7 +2011,7 @@ static int wpa_supplicant_ioctl(struct n + struct ieee_param *param; + uint ret = 0; + +- if (p->length < sizeof(struct ieee_param) || !p->pointer) { ++ if (!p->pointer || p->length != sizeof(struct ieee_param)) { + ret = -EINVAL; + goto out; + } diff --git a/queue-5.5/staging-rtl8188eu-fix-potential-security-hole.patch b/queue-5.5/staging-rtl8188eu-fix-potential-security-hole.patch new file mode 100644 index 00000000000..49aa12be936 --- /dev/null +++ b/queue-5.5/staging-rtl8188eu-fix-potential-security-hole.patch @@ -0,0 +1,40 @@ +From 499c405b2b80bb3a04425ba3541d20305e014d3e Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Mon, 10 Feb 2020 12:02:30 -0600 +Subject: staging: rtl8188eu: Fix potential security hole + +From: Larry Finger + +commit 499c405b2b80bb3a04425ba3541d20305e014d3e upstream. + +In routine rtw_hostapd_ioctl(), the user-controlled p->length is assumed +to be at least the size of struct ieee_param size, but this assumption is +never checked. This could result in out-of-bounds read/write on kernel +heap in case a p->length less than the size of struct ieee_param is +specified by the user. If p->length is allowed to be greater than the size +of the struct, then a malicious user could be wasting kernel memory. +Fixes commit a2c60d42d97c ("Add files for new driver - part 16"). + +Reported by: Pietro Oliva +Cc: Pietro Oliva +Cc: Stable +Fixes: a2c60d42d97c ("staging: r8188eu: Add files for new driver - part 16") +Signed-off-by: Larry Finger +Link: https://lore.kernel.org/r/20200210180235.21691-2-Larry.Finger@lwfinger.net +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/rtl8188eu/os_dep/ioctl_linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c ++++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +@@ -2798,7 +2798,7 @@ static int rtw_hostapd_ioctl(struct net_ + goto out; + } + +- if (!p->pointer) { ++ if (!p->pointer || p->length != sizeof(struct ieee_param)) { + ret = -EINVAL; + goto out; + } diff --git a/queue-5.5/staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch b/queue-5.5/staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch new file mode 100644 index 00000000000..60598700541 --- /dev/null +++ b/queue-5.5/staging-rtl8723bs-fix-potential-overuse-of-kernel-memory.patch @@ -0,0 +1,38 @@ +From 23954cb078febfc63a755301fe77e06bccdb4d2a Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Mon, 10 Feb 2020 12:02:33 -0600 +Subject: staging: rtl8723bs: Fix potential overuse of kernel memory + +From: Larry Finger + +commit 23954cb078febfc63a755301fe77e06bccdb4d2a upstream. + +In routine wpa_supplicant_ioctl(), the user-controlled p->length is +checked to be at least the size of struct ieee_param size, but the code +does not detect the case where p->length is greater than the size +of the struct, thus a malicious user could be wasting kernel memory. +Fixes commit 554c0a3abf216 ("staging: Add rtl8723bs sdio wifi driver"). + +Reported by: Pietro Oliva +Cc: Pietro Oliva +Cc: Stable +Fixes: 554c0a3abf216 ("staging: Add rtl8723bs sdio wifi driver"). +Signed-off-by: Larry Finger +Link: https://lore.kernel.org/r/20200210180235.21691-5-Larry.Finger@lwfinger.net +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c ++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c +@@ -3373,7 +3373,7 @@ static int wpa_supplicant_ioctl(struct n + + /* down(&ieee->wx_sem); */ + +- if (p->length < sizeof(struct ieee_param) || !p->pointer) { ++ if (!p->pointer || p->length != sizeof(struct ieee_param)) { + ret = -EINVAL; + goto out; + } diff --git a/queue-5.5/staging-rtl8723bs-fix-potential-security-hole.patch b/queue-5.5/staging-rtl8723bs-fix-potential-security-hole.patch new file mode 100644 index 00000000000..da03d486560 --- /dev/null +++ b/queue-5.5/staging-rtl8723bs-fix-potential-security-hole.patch @@ -0,0 +1,40 @@ +From ac33597c0c0d1d819dccfe001bcd0acef7107e7c Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Mon, 10 Feb 2020 12:02:31 -0600 +Subject: staging: rtl8723bs: Fix potential security hole + +From: Larry Finger + +commit ac33597c0c0d1d819dccfe001bcd0acef7107e7c upstream. + +In routine rtw_hostapd_ioctl(), the user-controlled p->length is assumed +to be at least the size of struct ieee_param size, but this assumption is +never checked. This could result in out-of-bounds read/write on kernel +heap in case a p->length less than the size of struct ieee_param is +specified by the user. If p->length is allowed to be greater than the size +of the struct, then a malicious user could be wasting kernel memory. +Fixes commit 554c0a3abf216 ("0taging: Add rtl8723bs sdio wifi driver"). + +Reported by: Pietro Oliva +Cc: Pietro Oliva +Cc: Stable +Fixes 554c0a3abf216 ("0taging: Add rtl8723bs sdio wifi driver"). +Signed-off-by: Larry Finger +Link: https://lore.kernel.org/r/20200210180235.21691-3-Larry.Finger@lwfinger.net +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/staging/rtl8723bs/os_dep/ioctl_linux.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c ++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c +@@ -4207,7 +4207,7 @@ static int rtw_hostapd_ioctl(struct net_ + + + /* if (p->length < sizeof(struct ieee_param) || !p->pointer) { */ +- if (!p->pointer) { ++ if (!p->pointer || p->length != sizeof(*param)) { + ret = -EINVAL; + goto out; + } diff --git a/queue-5.5/usb-core-add-endpoint-blacklist-quirk.patch b/queue-5.5/usb-core-add-endpoint-blacklist-quirk.patch new file mode 100644 index 00000000000..6f10571e0b4 --- /dev/null +++ b/queue-5.5/usb-core-add-endpoint-blacklist-quirk.patch @@ -0,0 +1,122 @@ +From 73f8bda9b5dc1c69df2bc55c0cbb24461a6391a9 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 3 Feb 2020 16:38:28 +0100 +Subject: USB: core: add endpoint-blacklist quirk + +From: Johan Hovold + +commit 73f8bda9b5dc1c69df2bc55c0cbb24461a6391a9 upstream. + +Add a new device quirk that can be used to blacklist endpoints. + +Since commit 3e4f8e21c4f2 ("USB: core: fix check for duplicate +endpoints") USB core ignores any duplicate endpoints found during +descriptor parsing. + +In order to handle devices where the first interfaces with duplicate +endpoints are the ones that should have their endpoints ignored, we need +to add a blacklist. + +Tested-by: edes +Cc: stable +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20200203153830.26394-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/config.c | 11 +++++++++++ + drivers/usb/core/quirks.c | 32 ++++++++++++++++++++++++++++++++ + drivers/usb/core/usb.h | 3 +++ + include/linux/usb/quirks.h | 3 +++ + 4 files changed, 49 insertions(+) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -256,6 +256,7 @@ static int usb_parse_endpoint(struct dev + struct usb_host_interface *ifp, int num_ep, + unsigned char *buffer, int size) + { ++ struct usb_device *udev = to_usb_device(ddev); + unsigned char *buffer0 = buffer; + struct usb_endpoint_descriptor *d; + struct usb_host_endpoint *endpoint; +@@ -297,6 +298,16 @@ static int usb_parse_endpoint(struct dev + goto skip_to_next_endpoint_or_interface_descriptor; + } + ++ /* Ignore blacklisted endpoints */ ++ if (udev->quirks & USB_QUIRK_ENDPOINT_BLACKLIST) { ++ if (usb_endpoint_is_blacklisted(udev, ifp, d)) { ++ dev_warn(ddev, "config %d interface %d altsetting %d has a blacklisted 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]; + ++ifp->desc.bNumEndpoints; + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -472,6 +472,38 @@ static const struct usb_device_id usb_am + { } /* terminating entry must be last */ + }; + ++/* ++ * Entries for blacklisted endpoints that should be ignored when parsing ++ * configuration descriptors. ++ * ++ * Matched for devices with USB_QUIRK_ENDPOINT_BLACKLIST. ++ */ ++static const struct usb_device_id usb_endpoint_blacklist[] = { ++ { } ++}; ++ ++bool usb_endpoint_is_blacklisted(struct usb_device *udev, ++ struct usb_host_interface *intf, ++ struct usb_endpoint_descriptor *epd) ++{ ++ const struct usb_device_id *id; ++ unsigned int address; ++ ++ for (id = usb_endpoint_blacklist; id->match_flags; ++id) { ++ if (!usb_match_device(udev, id)) ++ continue; ++ ++ if (!usb_match_one_id_intf(udev, intf, id)) ++ continue; ++ ++ address = id->driver_info; ++ if (address == epd->bEndpointAddress) ++ return true; ++ } ++ ++ return false; ++} ++ + static bool usb_match_any_interface(struct usb_device *udev, + const struct usb_device_id *id) + { +--- a/drivers/usb/core/usb.h ++++ b/drivers/usb/core/usb.h +@@ -37,6 +37,9 @@ extern void usb_authorize_interface(stru + extern void usb_detect_quirks(struct usb_device *udev); + extern void usb_detect_interface_quirks(struct usb_device *udev); + extern void usb_release_quirk_list(void); ++extern bool usb_endpoint_is_blacklisted(struct usb_device *udev, ++ struct usb_host_interface *intf, ++ struct usb_endpoint_descriptor *epd); + extern int usb_remove_device(struct usb_device *udev); + + extern int usb_get_device_descriptor(struct usb_device *dev, +--- a/include/linux/usb/quirks.h ++++ b/include/linux/usb/quirks.h +@@ -69,4 +69,7 @@ + /* Hub needs extra delay after resetting its port. */ + #define USB_QUIRK_HUB_SLOW_RESET BIT(14) + ++/* device has blacklisted endpoints */ ++#define USB_QUIRK_ENDPOINT_BLACKLIST BIT(15) ++ + #endif /* __LINUX_USB_QUIRKS_H */ diff --git a/queue-5.5/usb-dwc2-fix-set-clear_feature-and-get_status-flows.patch b/queue-5.5/usb-dwc2-fix-set-clear_feature-and-get_status-flows.patch new file mode 100644 index 00000000000..29eaf0f302e --- /dev/null +++ b/queue-5.5/usb-dwc2-fix-set-clear_feature-and-get_status-flows.patch @@ -0,0 +1,88 @@ +From 9a0d6f7c0a83844baae1d6d85482863d2bf3b7a7 Mon Sep 17 00:00:00 2001 +From: Minas Harutyunyan +Date: Tue, 21 Jan 2020 14:17:07 +0400 +Subject: usb: dwc2: Fix SET/CLEAR_FEATURE and GET_STATUS flows + +From: Minas Harutyunyan + +commit 9a0d6f7c0a83844baae1d6d85482863d2bf3b7a7 upstream. + +SET/CLEAR_FEATURE for Remote Wakeup allowance not handled correctly. +GET_STATUS handling provided not correct data on DATA Stage. +Issue seen when gadget's dr_mode set to "otg" mode and connected +to MacOS. +Both are fixed and tested using USBCV Ch.9 tests. + +Signed-off-by: Minas Harutyunyan +Fixes: fa389a6d7726 ("usb: dwc2: gadget: Add remote_wakeup_allowed flag") +Tested-by: Jack Mitchell +Cc: stable@vger.kernel.org +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc2/gadget.c | 28 ++++++++++++++++------------ + 1 file changed, 16 insertions(+), 12 deletions(-) + +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -1632,6 +1632,7 @@ static int dwc2_hsotg_process_req_status + struct dwc2_hsotg_ep *ep0 = hsotg->eps_out[0]; + struct dwc2_hsotg_ep *ep; + __le16 reply; ++ u16 status; + int ret; + + dev_dbg(hsotg->dev, "%s: USB_REQ_GET_STATUS\n", __func__); +@@ -1643,11 +1644,10 @@ static int dwc2_hsotg_process_req_status + + switch (ctrl->bRequestType & USB_RECIP_MASK) { + case USB_RECIP_DEVICE: +- /* +- * bit 0 => self powered +- * bit 1 => remote wakeup +- */ +- reply = cpu_to_le16(0); ++ status = 1 << USB_DEVICE_SELF_POWERED; ++ status |= hsotg->remote_wakeup_allowed << ++ USB_DEVICE_REMOTE_WAKEUP; ++ reply = cpu_to_le16(status); + break; + + case USB_RECIP_INTERFACE: +@@ -1758,7 +1758,10 @@ static int dwc2_hsotg_process_req_featur + case USB_RECIP_DEVICE: + switch (wValue) { + case USB_DEVICE_REMOTE_WAKEUP: +- hsotg->remote_wakeup_allowed = 1; ++ if (set) ++ hsotg->remote_wakeup_allowed = 1; ++ else ++ hsotg->remote_wakeup_allowed = 0; + break; + + case USB_DEVICE_TEST_MODE: +@@ -1768,16 +1771,17 @@ static int dwc2_hsotg_process_req_featur + return -EINVAL; + + hsotg->test_mode = wIndex >> 8; +- ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0); +- if (ret) { +- dev_err(hsotg->dev, +- "%s: failed to send reply\n", __func__); +- return ret; +- } + break; + default: + return -ENOENT; + } ++ ++ ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0); ++ if (ret) { ++ dev_err(hsotg->dev, ++ "%s: failed to send reply\n", __func__); ++ return ret; ++ } + break; + + case USB_RECIP_ENDPOINT: diff --git a/queue-5.5/usb-dwc3-debug-fix-string-position-formatting-mixup-with-ret-and-len.patch b/queue-5.5/usb-dwc3-debug-fix-string-position-formatting-mixup-with-ret-and-len.patch new file mode 100644 index 00000000000..d293c05114f --- /dev/null +++ b/queue-5.5/usb-dwc3-debug-fix-string-position-formatting-mixup-with-ret-and-len.patch @@ -0,0 +1,132 @@ +From b32196e35bd7bbc8038db1aba1fbf022dc469b6a Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Mon, 10 Feb 2020 09:51:39 +0000 +Subject: usb: dwc3: debug: fix string position formatting mixup with ret and len + +From: Colin Ian King + +commit b32196e35bd7bbc8038db1aba1fbf022dc469b6a upstream. + +Currently the string formatting is mixing up the offset of ret and +len. Re-work the code to use just len, remove ret and use scnprintf +instead of snprintf and len position accumulation where required. +Remove the -ve return check since scnprintf never returns a failure +-ve size. Also break overly long lines to clean up checkpatch +warnings. + +Addresses-Coverity: ("Unused value") +Fixes: 1381a5113caf ("usb: dwc3: debug: purge usage of strcat") +Signed-off-by: Colin Ian King +Reviewed-by: Dan Carpenter +Cc: stable +Link: https://lore.kernel.org/r/20200210095139.328711-1-colin.king@canonical.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/debug.h | 39 +++++++++++++++------------------------ + 1 file changed, 15 insertions(+), 24 deletions(-) + +--- a/drivers/usb/dwc3/debug.h ++++ b/drivers/usb/dwc3/debug.h +@@ -256,86 +256,77 @@ static inline const char *dwc3_ep_event_ + u8 epnum = event->endpoint_number; + size_t len; + int status; +- int ret; + +- ret = snprintf(str, size, "ep%d%s: ", epnum >> 1, ++ len = scnprintf(str, size, "ep%d%s: ", epnum >> 1, + (epnum & 1) ? "in" : "out"); +- if (ret < 0) +- return "UNKNOWN"; + + status = event->status; + + switch (event->endpoint_event) { + case DWC3_DEPEVT_XFERCOMPLETE: +- len = strlen(str); +- snprintf(str + len, size - len, "Transfer Complete (%c%c%c)", ++ len += scnprintf(str + len, size - len, ++ "Transfer Complete (%c%c%c)", + status & DEPEVT_STATUS_SHORT ? 'S' : 's', + status & DEPEVT_STATUS_IOC ? 'I' : 'i', + status & DEPEVT_STATUS_LST ? 'L' : 'l'); + +- len = strlen(str); +- + if (epnum <= 1) +- snprintf(str + len, size - len, " [%s]", ++ scnprintf(str + len, size - len, " [%s]", + dwc3_ep0_state_string(ep0state)); + break; + case DWC3_DEPEVT_XFERINPROGRESS: +- len = strlen(str); +- +- snprintf(str + len, size - len, "Transfer In Progress [%d] (%c%c%c)", ++ scnprintf(str + len, size - len, ++ "Transfer In Progress [%d] (%c%c%c)", + event->parameters, + status & DEPEVT_STATUS_SHORT ? 'S' : 's', + status & DEPEVT_STATUS_IOC ? 'I' : 'i', + status & DEPEVT_STATUS_LST ? 'M' : 'm'); + break; + case DWC3_DEPEVT_XFERNOTREADY: +- len = strlen(str); +- +- snprintf(str + len, size - len, "Transfer Not Ready [%d]%s", ++ len += scnprintf(str + len, size - len, ++ "Transfer Not Ready [%d]%s", + event->parameters, + status & DEPEVT_STATUS_TRANSFER_ACTIVE ? + " (Active)" : " (Not Active)"); + +- len = strlen(str); +- + /* Control Endpoints */ + if (epnum <= 1) { + int phase = DEPEVT_STATUS_CONTROL_PHASE(event->status); + + switch (phase) { + case DEPEVT_STATUS_CONTROL_DATA: +- snprintf(str + ret, size - ret, ++ scnprintf(str + len, size - len, + " [Data Phase]"); + break; + case DEPEVT_STATUS_CONTROL_STATUS: +- snprintf(str + ret, size - ret, ++ scnprintf(str + len, size - len, + " [Status Phase]"); + } + } + break; + case DWC3_DEPEVT_RXTXFIFOEVT: +- snprintf(str + ret, size - ret, "FIFO"); ++ scnprintf(str + len, size - len, "FIFO"); + break; + case DWC3_DEPEVT_STREAMEVT: + status = event->status; + + switch (status) { + case DEPEVT_STREAMEVT_FOUND: +- snprintf(str + ret, size - ret, " Stream %d Found", ++ scnprintf(str + len, size - len, " Stream %d Found", + event->parameters); + break; + case DEPEVT_STREAMEVT_NOTFOUND: + default: +- snprintf(str + ret, size - ret, " Stream Not Found"); ++ scnprintf(str + len, size - len, " Stream Not Found"); + break; + } + + break; + case DWC3_DEPEVT_EPCMDCMPLT: +- snprintf(str + ret, size - ret, "Endpoint Command Complete"); ++ scnprintf(str + len, size - len, "Endpoint Command Complete"); + break; + default: +- snprintf(str, size, "UNKNOWN"); ++ scnprintf(str + len, size - len, "UNKNOWN"); + } + + return str; diff --git a/queue-5.5/usb-dwc3-gadget-check-for-ioc-lst-bit-in-trb-ctrl-fields.patch b/queue-5.5/usb-dwc3-gadget-check-for-ioc-lst-bit-in-trb-ctrl-fields.patch new file mode 100644 index 00000000000..9f0be36bf98 --- /dev/null +++ b/queue-5.5/usb-dwc3-gadget-check-for-ioc-lst-bit-in-trb-ctrl-fields.patch @@ -0,0 +1,70 @@ +From 5ee858975b13a9b40db00f456989a689fdbb296c Mon Sep 17 00:00:00 2001 +From: Anurag Kumar Vulisha +Date: Mon, 27 Jan 2020 19:30:46 +0000 +Subject: usb: dwc3: gadget: Check for IOC/LST bit in TRB->ctrl fields + +From: Anurag Kumar Vulisha + +commit 5ee858975b13a9b40db00f456989a689fdbb296c upstream. + +The current code in dwc3_gadget_ep_reclaim_completed_trb() will +check for IOC/LST bit in the event->status and returns if +IOC/LST bit is set. This logic doesn't work if multiple TRBs +are queued per request and the IOC/LST bit is set on the last +TRB of that request. + +Consider an example where a queued request has multiple queued +TRBs and IOC/LST bit is set only for the last TRB. In this case, +the core generates XferComplete/XferInProgress events only for +the last TRB (since IOC/LST are set only for the last TRB). As +per the logic in dwc3_gadget_ep_reclaim_completed_trb() +event->status is checked for IOC/LST bit and returns on the +first TRB. This leaves the remaining TRBs left unhandled. + +Similarly, if the gadget function enqueues an unaligned request +with sglist already in it, it should fail the same way, since we +will append another TRB to something that already uses more than +one TRB. + +To aviod this, this patch changes the code to check for IOC/LST +bits in TRB->ctrl instead. + +At a practical level, this patch resolves USB transfer stalls seen +with adb on dwc3 based HiKey960 after functionfs gadget added +scatter-gather support around v4.20. + +Cc: Felipe Balbi +Cc: Yang Fei +Cc: Thinh Nguyen +Cc: Tejas Joglekar +Cc: Andrzej Pietrasiewicz +Cc: Jack Pham +Cc: Todd Kjos +Cc: Greg KH +Cc: Linux USB List +Cc: stable +Tested-by: Tejas Joglekar +Reviewed-by: Thinh Nguyen +Signed-off-by: Anurag Kumar Vulisha +[jstultz: forward ported to mainline, reworded commit log, reworked + to only check trb->ctrl as suggested by Felipe] +Signed-off-by: John Stultz +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/gadget.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -2426,7 +2426,8 @@ static int dwc3_gadget_ep_reclaim_comple + if (event->status & DEPEVT_STATUS_SHORT && !chain) + return 1; + +- if (event->status & DEPEVT_STATUS_IOC) ++ if ((trb->ctrl & DWC3_TRB_CTRL_IOC) || ++ (trb->ctrl & DWC3_TRB_CTRL_LST)) + return 1; + + return 0; diff --git a/queue-5.5/usb-fix-novation-sourcecontrol-xl-after-suspend.patch b/queue-5.5/usb-fix-novation-sourcecontrol-xl-after-suspend.patch new file mode 100644 index 00000000000..54be01a1da1 --- /dev/null +++ b/queue-5.5/usb-fix-novation-sourcecontrol-xl-after-suspend.patch @@ -0,0 +1,33 @@ +From b692056db8ecc7f452b934f016c17348282b7699 Mon Sep 17 00:00:00 2001 +From: Richard Dodd +Date: Wed, 12 Feb 2020 14:22:18 +0000 +Subject: USB: Fix novation SourceControl XL after suspend + +From: Richard Dodd + +commit b692056db8ecc7f452b934f016c17348282b7699 upstream. + +Currently, the SourceControl will stay in power-down mode after resuming +from suspend. This patch resets the device after suspend to power it up. + +Signed-off-by: Richard Dodd +Cc: stable +Link: https://lore.kernel.org/r/20200212142220.36892-1-richard.o.dodd@gmail.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -449,6 +449,9 @@ static const struct usb_device_id usb_qu + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* novation SoundControl XL */ ++ { USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME }, ++ + { } /* terminating entry must be last */ + }; + diff --git a/queue-5.5/usb-hub-don-t-record-a-connect-change-event-during-reset-resume.patch b/queue-5.5/usb-hub-don-t-record-a-connect-change-event-during-reset-resume.patch new file mode 100644 index 00000000000..607804eafa4 --- /dev/null +++ b/queue-5.5/usb-hub-don-t-record-a-connect-change-event-during-reset-resume.patch @@ -0,0 +1,84 @@ +From 8099f58f1ecddf4f374f4828a3dff8397c7cbd74 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 31 Jan 2020 10:39:26 -0500 +Subject: USB: hub: Don't record a connect-change event during reset-resume + +From: Alan Stern + +commit 8099f58f1ecddf4f374f4828a3dff8397c7cbd74 upstream. + +Paul Zimmerman reports that his USB Bluetooth adapter sometimes +crashes following system resume, when it receives a +Get-Device-Descriptor request while it is busy doing something else. + +Such a request was added by commit a4f55d8b8c14 ("usb: hub: Check +device descriptor before resusciation"). It gets sent when the hub +driver's work thread checks whether a connect-change event on an +enabled port really indicates a new device has been connected, as +opposed to an old device momentarily disconnecting and then +reconnecting (which can happen with xHCI host controllers, since they +automatically enable connected ports). + +The same kind of thing occurs when a port's power session is lost +during system suspend. When the system wakes up it sees a +connect-change event on the port, and if the child device's +persist_enabled flag was set then hub_activate() sets the device's +reset_resume flag as well as the port's bit in hub->change_bits. The +reset-resume code then takes responsibility for checking that the same +device is still attached to the port, and it does this as part of the +device's resume pathway. By the time the hub driver's work thread +starts up again, the device has already been fully reinitialized and +is busy doing its own thing. There's no need for the work thread to +do the same check a second time, and in fact this unnecessary check is +what caused the problem that Paul observed. + +Note that performing the unnecessary check is not actually a bug. +Devices are supposed to be able to send descriptors back to the host +even when they are busy doing something else. The underlying cause of +Paul's problem lies in his Bluetooth adapter. Nevertheless, we +shouldn't perform the same check twice in a row -- and as a nice side +benefit, removing the extra check allows the Bluetooth adapter to work +more reliably. + +The work thread performs its check when it sees that the port's bit is +set in hub->change_bits. In this situation that bit is interpreted as +though a connect-change event had occurred on the port _after_ the +reset-resume, which is not what actually happened. + +One possible fix would be to make the reset-resume code clear the +port's bit in hub->change_bits. But it seems simpler to just avoid +setting the bit during hub_activate() in the first place. That's what +this patch does. + +(Proving that the patch is correct when CONFIG_PM is disabled requires +a little thought. In that setting hub_activate() will be called only +for initialization and resets, since there won't be any resumes or +reset-resumes. During initialization and hub resets the hub doesn't +have any child devices, and so this code path never gets executed.) + +Reported-and-tested-by: Paul Zimmerman +Signed-off-by: Alan Stern +Link: https://marc.info/?t=157949360700001&r=1&w=2 +CC: David Heinzelmann +CC: +Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2001311037460.1577-100000@iolanthe.rowland.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1217,11 +1217,6 @@ static void hub_activate(struct usb_hub + #ifdef CONFIG_PM + udev->reset_resume = 1; + #endif +- /* Don't set the change_bits when the device +- * was powered off. +- */ +- if (test_bit(port1, hub->power_bits)) +- set_bit(port1, hub->change_bits); + + } else { + /* The power session is gone; tell hub_wq */ diff --git a/queue-5.5/usb-hub-fix-the-broken-detection-of-usb3-device-in-smsc-hub.patch b/queue-5.5/usb-hub-fix-the-broken-detection-of-usb3-device-in-smsc-hub.patch new file mode 100644 index 00000000000..35afa95471b --- /dev/null +++ b/queue-5.5/usb-hub-fix-the-broken-detection-of-usb3-device-in-smsc-hub.patch @@ -0,0 +1,109 @@ +From 1208f9e1d758c991b0a46a1bd60c616b906bbe27 Mon Sep 17 00:00:00 2001 +From: Hardik Gajjar +Date: Thu, 6 Feb 2020 12:49:23 +0100 +Subject: USB: hub: Fix the broken detection of USB3 device in SMSC hub + +From: Hardik Gajjar + +commit 1208f9e1d758c991b0a46a1bd60c616b906bbe27 upstream. + +Renesas R-Car H3ULCB + Kingfisher Infotainment Board is either not able +to detect the USB3.0 mass storage devices or is detecting those as +USB2.0 high speed devices. + +The explanation given by Renesas is that, due to a HW issue, the XHCI +driver does not wake up after going to sleep on connecting a USB3.0 +device. + +In order to mitigate that, disable the auto-suspend feature +specifically for SMSC hubs from hub_probe() function, as a quirk. + +Renesas Kingfisher Infotainment Board has two USB3.0 ports (CN2) which +are connected via USB5534B 4-port SuperSpeed/Hi-Speed, low-power, +configurable hub controller. + +[1] SanDisk USB 3.0 device detected as USB-2.0 before the patch + [ 74.036390] usb 5-1.1: new high-speed USB device number 4 using xhci-hcd + [ 74.061598] usb 5-1.1: New USB device found, idVendor=0781, idProduct=5581, bcdDevice= 1.00 + [ 74.069976] usb 5-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 + [ 74.077303] usb 5-1.1: Product: Ultra + [ 74.080980] usb 5-1.1: Manufacturer: SanDisk + [ 74.085263] usb 5-1.1: SerialNumber: 4C530001110208116550 + +[2] SanDisk USB 3.0 device detected as USB-3.0 after the patch + [ 34.565078] usb 6-1.1: new SuperSpeed Gen 1 USB device number 3 using xhci-hcd + [ 34.588719] usb 6-1.1: New USB device found, idVendor=0781, idProduct=5581, bcdDevice= 1.00 + [ 34.597098] usb 6-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 + [ 34.604430] usb 6-1.1: Product: Ultra + [ 34.608110] usb 6-1.1: Manufacturer: SanDisk + [ 34.612397] usb 6-1.1: SerialNumber: 4C530001110208116550 + +Suggested-by: Alan Stern +Signed-off-by: Hardik Gajjar +Acked-by: Alan Stern +Tested-by: Eugeniu Rosca +Cc: stable +Link: https://lore.kernel.org/r/1580989763-32291-1-git-send-email-hgajjar@de.adit-jv.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 15 +++++++++++++++ + drivers/usb/core/hub.h | 1 + + 2 files changed, 16 insertions(+) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -38,7 +38,9 @@ + #include "otg_whitelist.h" + + #define USB_VENDOR_GENESYS_LOGIC 0x05e3 ++#define USB_VENDOR_SMSC 0x0424 + #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01 ++#define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02 + + #define USB_TP_TRANSMISSION_DELAY 40 /* ns */ + #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */ +@@ -1726,6 +1728,10 @@ static void hub_disconnect(struct usb_in + kfree(hub->buffer); + + pm_suspend_ignore_children(&intf->dev, false); ++ ++ if (hub->quirk_disable_autosuspend) ++ usb_autopm_put_interface(intf); ++ + kref_put(&hub->kref, hub_release); + } + +@@ -1858,6 +1864,11 @@ static int hub_probe(struct usb_interfac + if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND) + hub->quirk_check_port_auto_suspend = 1; + ++ if (id->driver_info & HUB_QUIRK_DISABLE_AUTOSUSPEND) { ++ hub->quirk_disable_autosuspend = 1; ++ usb_autopm_get_interface(intf); ++ } ++ + if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) + return 0; + +@@ -5594,6 +5605,10 @@ out_hdev_lock: + } + + static const struct usb_device_id hub_id_table[] = { ++ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_CLASS, ++ .idVendor = USB_VENDOR_SMSC, ++ .bInterfaceClass = USB_CLASS_HUB, ++ .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_INT_CLASS, + .idVendor = USB_VENDOR_GENESYS_LOGIC, +--- a/drivers/usb/core/hub.h ++++ b/drivers/usb/core/hub.h +@@ -61,6 +61,7 @@ struct usb_hub { + unsigned quiescing:1; + unsigned disconnected:1; + unsigned in_reset:1; ++ unsigned quirk_disable_autosuspend:1; + + unsigned quirk_check_port_auto_suspend:1; + diff --git a/queue-5.5/usb-quirks-blacklist-duplicate-ep-on-sound-devices-usbpre2.patch b/queue-5.5/usb-quirks-blacklist-duplicate-ep-on-sound-devices-usbpre2.patch new file mode 100644 index 00000000000..ff92264b8d5 --- /dev/null +++ b/queue-5.5/usb-quirks-blacklist-duplicate-ep-on-sound-devices-usbpre2.patch @@ -0,0 +1,146 @@ +From bdd1b147b8026df0e4260b387026b251d888ed01 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 3 Feb 2020 16:38:29 +0100 +Subject: USB: quirks: blacklist duplicate ep on Sound Devices USBPre2 + +From: Johan Hovold + +commit bdd1b147b8026df0e4260b387026b251d888ed01 upstream. + +This device has a broken vendor-specific altsetting for interface 1, +where endpoint 0x85 is declared as an isochronous endpoint despite being +used by interface 2 for audio capture. + +Device Descriptor: + bLength 18 + bDescriptorType 1 + bcdUSB 2.00 + bDeviceClass 239 Miscellaneous Device + bDeviceSubClass 2 + bDeviceProtocol 1 Interface Association + bMaxPacketSize0 64 + idVendor 0x0926 + idProduct 0x0202 + bcdDevice 1.00 + iManufacturer 1 Sound Devices + iProduct 2 USBPre2 + iSerial 3 [...] + bNumConfigurations 1 + +[...] + + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 1 + bAlternateSetting 3 + bNumEndpoints 2 + bInterfaceClass 255 Vendor Specific Class + bInterfaceSubClass 0 + bInterfaceProtocol 0 + iInterface 0 + Endpoint Descriptor: + bLength 7 + bDescriptorType 5 + bEndpointAddress 0x85 EP 5 IN + bmAttributes 5 + Transfer Type Isochronous + Synch Type Asynchronous + Usage Type Data + wMaxPacketSize 0x0126 1x 294 bytes + bInterval 1 + +[...] + + Interface Descriptor: + bLength 9 + bDescriptorType 4 + bInterfaceNumber 2 + bAlternateSetting 1 + bNumEndpoints 1 + bInterfaceClass 1 Audio + bInterfaceSubClass 2 Streaming + bInterfaceProtocol 0 + iInterface 0 + AudioStreaming Interface Descriptor: + bLength 7 + bDescriptorType 36 + bDescriptorSubtype 1 (AS_GENERAL) + bTerminalLink 4 + bDelay 1 frames + wFormatTag 0x0001 PCM + AudioStreaming Interface Descriptor: + bLength 26 + bDescriptorType 36 + bDescriptorSubtype 2 (FORMAT_TYPE) + bFormatType 1 (FORMAT_TYPE_I) + bNrChannels 2 + bSubframeSize 2 + bBitResolution 16 + bSamFreqType 6 Discrete + tSamFreq[ 0] 8000 + tSamFreq[ 1] 16000 + tSamFreq[ 2] 24000 + tSamFreq[ 3] 32000 + tSamFreq[ 4] 44100 + tSamFreq[ 5] 48000 + Endpoint Descriptor: + bLength 9 + bDescriptorType 5 + bEndpointAddress 0x85 EP 5 IN + bmAttributes 5 + Transfer Type Isochronous + Synch Type Asynchronous + Usage Type Data + wMaxPacketSize 0x0126 1x 294 bytes + bInterval 4 + bRefresh 0 + bSynchAddress 0 + AudioStreaming Endpoint Descriptor: + bLength 7 + bDescriptorType 37 + bDescriptorSubtype 1 (EP_GENERAL) + bmAttributes 0x01 + Sampling Frequency + bLockDelayUnits 2 Decoded PCM samples + wLockDelay 0x0000 + +Since commit 3e4f8e21c4f2 ("USB: core: fix check for duplicate +endpoints") USB core ignores any duplicate endpoints found during +descriptor parsing, but in this case we need to ignore the first +instance in order to avoid breaking the audio capture interface. + +Fixes: 3e4f8e21c4f2 ("USB: core: fix check for duplicate endpoints") +Cc: stable +Reported-by: edes +Tested-by: edes +Link: https://lore.kernel.org/r/20200201105829.5682c887@acme7.acmenet +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20200203153830.26394-3-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/quirks.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -354,6 +354,10 @@ static const struct usb_device_id usb_qu + { USB_DEVICE(0x0904, 0x6103), .driver_info = + USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL }, + ++ /* Sound Devices USBPre2 */ ++ { USB_DEVICE(0x0926, 0x0202), .driver_info = ++ USB_QUIRK_ENDPOINT_BLACKLIST }, ++ + /* Keytouch QWERTY Panel keyboard */ + { USB_DEVICE(0x0926, 0x3333), .driver_info = + USB_QUIRK_CONFIG_INTF_STRINGS }, +@@ -479,6 +483,7 @@ static const struct usb_device_id usb_am + * Matched for devices with USB_QUIRK_ENDPOINT_BLACKLIST. + */ + static const struct usb_device_id usb_endpoint_blacklist[] = { ++ { USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0202, 1), .driver_info = 0x85 }, + { } + }; + diff --git a/queue-5.5/usb-uas-fix-a-plug-unplug-racing.patch b/queue-5.5/usb-uas-fix-a-plug-unplug-racing.patch new file mode 100644 index 00000000000..231dbd941f0 --- /dev/null +++ b/queue-5.5/usb-uas-fix-a-plug-unplug-racing.patch @@ -0,0 +1,100 @@ +From 3e99862c05a9caa5a27969f41566b428696f5a9a Mon Sep 17 00:00:00 2001 +From: EJ Hsu +Date: Thu, 30 Jan 2020 01:25:06 -0800 +Subject: usb: uas: fix a plug & unplug racing + +From: EJ Hsu + +commit 3e99862c05a9caa5a27969f41566b428696f5a9a upstream. + +When a uas disk is plugged into an external hub, uas_probe() +will be called by the hub thread to do the probe. It will +first create a SCSI host and then do the scan for this host. +During the scan, it will probe the LUN using SCSI INQUERY command +which will be packed in the URB and submitted to uas disk. + +There might be a chance that this external hub with uas disk +attached is unplugged during the scan. In this case, uas driver +will fail to submit the URB (due to the NOTATTACHED state of uas +device) and try to put this SCSI command back to request queue +waiting for next chance to run. + +In normal case, this cycle will terminate when hub thread gets +disconnection event and calls into uas_disconnect() accordingly. +But in this case, uas_disconnect() will not be called because +hub thread of external hub gets stuck waiting for the completion +of this SCSI command. A deadlock happened. + +In this fix, uas will call scsi_scan_host() asynchronously to +avoid the blocking of hub thread. + +Signed-off-by: EJ Hsu +Acked-by: Oliver Neukum +Cc: stable +Link: https://lore.kernel.org/r/20200130092506.102760-1-ejh@nvidia.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/uas.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -45,6 +45,7 @@ struct uas_dev_info { + struct scsi_cmnd *cmnd[MAX_CMNDS]; + spinlock_t lock; + struct work_struct work; ++ struct work_struct scan_work; /* for async scanning */ + }; + + enum { +@@ -114,6 +115,17 @@ out: + spin_unlock_irqrestore(&devinfo->lock, flags); + } + ++static void uas_scan_work(struct work_struct *work) ++{ ++ struct uas_dev_info *devinfo = ++ container_of(work, struct uas_dev_info, scan_work); ++ struct Scsi_Host *shost = usb_get_intfdata(devinfo->intf); ++ ++ dev_dbg(&devinfo->intf->dev, "starting scan\n"); ++ scsi_scan_host(shost); ++ dev_dbg(&devinfo->intf->dev, "scan complete\n"); ++} ++ + static void uas_add_work(struct uas_cmd_info *cmdinfo) + { + struct scsi_pointer *scp = (void *)cmdinfo; +@@ -982,6 +994,7 @@ static int uas_probe(struct usb_interfac + init_usb_anchor(&devinfo->data_urbs); + spin_lock_init(&devinfo->lock); + INIT_WORK(&devinfo->work, uas_do_work); ++ INIT_WORK(&devinfo->scan_work, uas_scan_work); + + result = uas_configure_endpoints(devinfo); + if (result) +@@ -998,7 +1011,9 @@ static int uas_probe(struct usb_interfac + if (result) + goto free_streams; + +- scsi_scan_host(shost); ++ /* Submit the delayed_work for SCSI-device scanning */ ++ schedule_work(&devinfo->scan_work); ++ + return result; + + free_streams: +@@ -1166,6 +1181,12 @@ static void uas_disconnect(struct usb_in + usb_kill_anchored_urbs(&devinfo->data_urbs); + uas_zap_pending(devinfo, DID_NO_CONNECT); + ++ /* ++ * Prevent SCSI scanning (if it hasn't started yet) ++ * or wait for the SCSI-scanning routine to stop. ++ */ ++ cancel_work_sync(&devinfo->scan_work); ++ + scsi_remove_host(shost); + uas_free_streams(devinfo); + scsi_host_put(shost);