From f5c57d09c792a9b6604ad0dbb046cb6c77c64fa2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 8 Feb 2021 11:26:24 +0100 Subject: [PATCH] 4.14-stable patches added patches: cifs-report-error-instead-of-invalid-when-revalidating-a-dentry-fails.patch kretprobe-avoid-re-registration-of-the-same-kretprobe-earlier.patch mac80211-fix-station-rate-table-updates-on-assoc.patch ovl-fix-dentry-leak-in-ovl_get_redirect.patch usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch xhci-fix-bounce-buffer-usage-for-non-sg-list-case.patch --- ...lid-when-revalidating-a-dentry-fails.patch | 74 +++++++++++++++ ...ration-of-the-same-kretprobe-earlier.patch | 52 +++++++++++ ...-station-rate-table-updates-on-assoc.patch | 51 +++++++++++ ...-fix-dentry-leak-in-ovl_get_redirect.patch | 91 +++++++++++++++++++ queue-4.14/series | 8 ++ ...nt-direction-check-in-ep_from_windex.patch | 74 +++++++++++++++ ...legacy-fix-an-error-code-in-eth_bind.patch | 35 +++++++ ...et_interface-if-there-s-a-single-alt.patch | 51 +++++++++++ ...ce-buffer-usage-for-non-sg-list-case.patch | 82 +++++++++++++++++ 9 files changed, 518 insertions(+) create mode 100644 queue-4.14/cifs-report-error-instead-of-invalid-when-revalidating-a-dentry-fails.patch create mode 100644 queue-4.14/kretprobe-avoid-re-registration-of-the-same-kretprobe-earlier.patch create mode 100644 queue-4.14/mac80211-fix-station-rate-table-updates-on-assoc.patch create mode 100644 queue-4.14/ovl-fix-dentry-leak-in-ovl_get_redirect.patch create mode 100644 queue-4.14/usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch create mode 100644 queue-4.14/usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch create mode 100644 queue-4.14/usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch create mode 100644 queue-4.14/xhci-fix-bounce-buffer-usage-for-non-sg-list-case.patch diff --git a/queue-4.14/cifs-report-error-instead-of-invalid-when-revalidating-a-dentry-fails.patch b/queue-4.14/cifs-report-error-instead-of-invalid-when-revalidating-a-dentry-fails.patch new file mode 100644 index 00000000000..b7e936abc3c --- /dev/null +++ b/queue-4.14/cifs-report-error-instead-of-invalid-when-revalidating-a-dentry-fails.patch @@ -0,0 +1,74 @@ +From 21b200d091826a83aafc95d847139b2b0582f6d1 Mon Sep 17 00:00:00 2001 +From: Aurelien Aptel +Date: Fri, 5 Feb 2021 15:42:48 +0100 +Subject: cifs: report error instead of invalid when revalidating a dentry fails + +From: Aurelien Aptel + +commit 21b200d091826a83aafc95d847139b2b0582f6d1 upstream. + +Assuming +- //HOST/a is mounted on /mnt +- //HOST/b is mounted on /mnt/b + +On a slow connection, running 'df' and killing it while it's +processing /mnt/b can make cifs_get_inode_info() returns -ERESTARTSYS. + +This triggers the following chain of events: +=> the dentry revalidation fail +=> dentry is put and released +=> superblock associated with the dentry is put +=> /mnt/b is unmounted + +This patch makes cifs_d_revalidate() return the error instead of 0 +(invalid) when cifs_revalidate_dentry() fails, except for ENOENT (file +deleted) and ESTALE (file recreated). + +Signed-off-by: Aurelien Aptel +Suggested-by: Shyam Prasad N +Reviewed-by: Shyam Prasad N +CC: stable@vger.kernel.org +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/cifs/dir.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +--- a/fs/cifs/dir.c ++++ b/fs/cifs/dir.c +@@ -841,6 +841,7 @@ static int + cifs_d_revalidate(struct dentry *direntry, unsigned int flags) + { + struct inode *inode; ++ int rc; + + if (flags & LOOKUP_RCU) + return -ECHILD; +@@ -850,8 +851,25 @@ cifs_d_revalidate(struct dentry *direntr + if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode))) + CIFS_I(inode)->time = 0; /* force reval */ + +- if (cifs_revalidate_dentry(direntry)) +- return 0; ++ rc = cifs_revalidate_dentry(direntry); ++ if (rc) { ++ cifs_dbg(FYI, "cifs_revalidate_dentry failed with rc=%d", rc); ++ switch (rc) { ++ case -ENOENT: ++ case -ESTALE: ++ /* ++ * Those errors mean the dentry is invalid ++ * (file was deleted or recreated) ++ */ ++ return 0; ++ default: ++ /* ++ * Otherwise some unexpected error happened ++ * report it as-is to VFS layer ++ */ ++ return rc; ++ } ++ } + else { + /* + * If the inode wasn't known to be a dfs entry when diff --git a/queue-4.14/kretprobe-avoid-re-registration-of-the-same-kretprobe-earlier.patch b/queue-4.14/kretprobe-avoid-re-registration-of-the-same-kretprobe-earlier.patch new file mode 100644 index 00000000000..b70425a3736 --- /dev/null +++ b/queue-4.14/kretprobe-avoid-re-registration-of-the-same-kretprobe-earlier.patch @@ -0,0 +1,52 @@ +From 0188b87899ffc4a1d36a0badbe77d56c92fd91dc Mon Sep 17 00:00:00 2001 +From: Wang ShaoBo +Date: Thu, 28 Jan 2021 20:44:27 +0800 +Subject: kretprobe: Avoid re-registration of the same kretprobe earlier + +From: Wang ShaoBo + +commit 0188b87899ffc4a1d36a0badbe77d56c92fd91dc upstream. + +Our system encountered a re-init error when re-registering same kretprobe, +where the kretprobe_instance in rp->free_instances is illegally accessed +after re-init. + +Implementation to avoid re-registration has been introduced for kprobe +before, but lags for register_kretprobe(). We must check if kprobe has +been re-registered before re-initializing kretprobe, otherwise it will +destroy the data struct of kretprobe registered, which can lead to memory +leak, system crash, also some unexpected behaviors. + +We use check_kprobe_rereg() to check if kprobe has been re-registered +before running register_kretprobe()'s body, for giving a warning message +and terminate registration process. + +Link: https://lkml.kernel.org/r/20210128124427.2031088-1-bobo.shaobowang@huawei.com + +Cc: stable@vger.kernel.org +Fixes: 1f0ab40976460 ("kprobes: Prevent re-registration of the same kprobe") +[ The above commit should have been done for kretprobes too ] +Acked-by: Naveen N. Rao +Acked-by: Ananth N Mavinakayanahalli +Acked-by: Masami Hiramatsu +Signed-off-by: Wang ShaoBo +Signed-off-by: Cheng Jian +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/kprobes.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/kernel/kprobes.c ++++ b/kernel/kprobes.c +@@ -1989,6 +1989,10 @@ int register_kretprobe(struct kretprobe + if (!kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset)) + return -EINVAL; + ++ /* If only rp->kp.addr is specified, check reregistering kprobes */ ++ if (rp->kp.addr && check_kprobe_rereg(&rp->kp)) ++ return -EINVAL; ++ + if (kretprobe_blacklist_size) { + addr = kprobe_addr(&rp->kp); + if (IS_ERR(addr)) diff --git a/queue-4.14/mac80211-fix-station-rate-table-updates-on-assoc.patch b/queue-4.14/mac80211-fix-station-rate-table-updates-on-assoc.patch new file mode 100644 index 00000000000..28c5275bb53 --- /dev/null +++ b/queue-4.14/mac80211-fix-station-rate-table-updates-on-assoc.patch @@ -0,0 +1,51 @@ +From 18fe0fae61252b5ae6e26553e2676b5fac555951 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Mon, 1 Feb 2021 09:33:24 +0100 +Subject: mac80211: fix station rate table updates on assoc + +From: Felix Fietkau + +commit 18fe0fae61252b5ae6e26553e2676b5fac555951 upstream. + +If the driver uses .sta_add, station entries are only uploaded after the sta +is in assoc state. Fix early station rate table updates by deferring them +until the sta has been uploaded. + +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +Link: https://lore.kernel.org/r/20210201083324.3134-1-nbd@nbd.name +[use rcu_access_pointer() instead since we won't dereference here] +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/driver-ops.c | 5 ++++- + net/mac80211/rate.c | 3 ++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/net/mac80211/driver-ops.c ++++ b/net/mac80211/driver-ops.c +@@ -128,8 +128,11 @@ int drv_sta_state(struct ieee80211_local + } else if (old_state == IEEE80211_STA_AUTH && + new_state == IEEE80211_STA_ASSOC) { + ret = drv_sta_add(local, sdata, &sta->sta); +- if (ret == 0) ++ if (ret == 0) { + sta->uploaded = true; ++ if (rcu_access_pointer(sta->sta.rates)) ++ drv_sta_rate_tbl_update(local, sdata, &sta->sta); ++ } + } else if (old_state == IEEE80211_STA_ASSOC && + new_state == IEEE80211_STA_AUTH) { + drv_sta_remove(local, sdata, &sta->sta); +--- a/net/mac80211/rate.c ++++ b/net/mac80211/rate.c +@@ -941,7 +941,8 @@ int rate_control_set_rates(struct ieee80 + if (old) + kfree_rcu(old, rcu_head); + +- drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta); ++ if (sta->uploaded) ++ drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta); + + ieee80211_sta_set_expected_throughput(pubsta, sta_get_expected_throughput(sta)); + diff --git a/queue-4.14/ovl-fix-dentry-leak-in-ovl_get_redirect.patch b/queue-4.14/ovl-fix-dentry-leak-in-ovl_get_redirect.patch new file mode 100644 index 00000000000..24aa817c20e --- /dev/null +++ b/queue-4.14/ovl-fix-dentry-leak-in-ovl_get_redirect.patch @@ -0,0 +1,91 @@ +From e04527fefba6e4e66492f122cf8cc6314f3cf3bf Mon Sep 17 00:00:00 2001 +From: Liangyan +Date: Tue, 22 Dec 2020 11:06:26 +0800 +Subject: ovl: fix dentry leak in ovl_get_redirect +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Liangyan + +commit e04527fefba6e4e66492f122cf8cc6314f3cf3bf upstream. + +We need to lock d_parent->d_lock before dget_dlock, or this may +have d_lockref updated parallelly like calltrace below which will +cause dentry->d_lockref leak and risk a crash. + + CPU 0 CPU 1 +ovl_set_redirect lookup_fast + ovl_get_redirect __d_lookup + dget_dlock + //no lock protection here spin_lock(&dentry->d_lock) + dentry->d_lockref.count++ dentry->d_lockref.count++ + +[   49.799059] PGD 800000061fed7067 P4D 800000061fed7067 PUD 61fec5067 PMD 0 +[   49.799689] Oops: 0002 [#1] SMP PTI +[   49.800019] CPU: 2 PID: 2332 Comm: node Not tainted 4.19.24-7.20.al7.x86_64 #1 +[   49.800678] Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS 8a46cfe 04/01/2014 +[   49.801380] RIP: 0010:_raw_spin_lock+0xc/0x20 +[   49.803470] RSP: 0018:ffffac6fc5417e98 EFLAGS: 00010246 +[   49.803949] RAX: 0000000000000000 RBX: ffff93b8da3446c0 RCX: 0000000a00000000 +[   49.804600] RDX: 0000000000000001 RSI: 000000000000000a RDI: 0000000000000088 +[   49.805252] RBP: 0000000000000000 R08: 0000000000000000 R09: ffffffff993cf040 +[   49.805898] R10: ffff93b92292e580 R11: ffffd27f188a4b80 R12: 0000000000000000 +[   49.806548] R13: 00000000ffffff9c R14: 00000000fffffffe R15: ffff93b8da3446c0 +[   49.807200] FS:  00007ffbedffb700(0000) GS:ffff93b927880000(0000) knlGS:0000000000000000 +[   49.807935] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[   49.808461] CR2: 0000000000000088 CR3: 00000005e3f74006 CR4: 00000000003606a0 +[   49.809113] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[   49.809758] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +[   49.810410] Call Trace: +[   49.810653]  d_delete+0x2c/0xb0 +[   49.810951]  vfs_rmdir+0xfd/0x120 +[   49.811264]  do_rmdir+0x14f/0x1a0 +[   49.811573]  do_syscall_64+0x5b/0x190 +[   49.811917]  entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[   49.812385] RIP: 0033:0x7ffbf505ffd7 +[   49.814404] RSP: 002b:00007ffbedffada8 EFLAGS: 00000297 ORIG_RAX: 0000000000000054 +[   49.815098] RAX: ffffffffffffffda RBX: 00007ffbedffb640 RCX: 00007ffbf505ffd7 +[   49.815744] RDX: 0000000004449700 RSI: 0000000000000000 RDI: 0000000006c8cd50 +[   49.816394] RBP: 00007ffbedffaea0 R08: 0000000000000000 R09: 0000000000017d0b +[   49.817038] R10: 0000000000000000 R11: 0000000000000297 R12: 0000000000000012 +[   49.817687] R13: 00000000072823d8 R14: 00007ffbedffb700 R15: 00000000072823d8 +[   49.818338] Modules linked in: pvpanic cirrusfb button qemu_fw_cfg atkbd libps2 i8042 +[   49.819052] CR2: 0000000000000088 +[   49.819368] ---[ end trace 4e652b8aa299aa2d ]--- +[   49.819796] RIP: 0010:_raw_spin_lock+0xc/0x20 +[   49.821880] RSP: 0018:ffffac6fc5417e98 EFLAGS: 00010246 +[   49.822363] RAX: 0000000000000000 RBX: ffff93b8da3446c0 RCX: 0000000a00000000 +[   49.823008] RDX: 0000000000000001 RSI: 000000000000000a RDI: 0000000000000088 +[   49.823658] RBP: 0000000000000000 R08: 0000000000000000 R09: ffffffff993cf040 +[   49.825404] R10: ffff93b92292e580 R11: ffffd27f188a4b80 R12: 0000000000000000 +[   49.827147] R13: 00000000ffffff9c R14: 00000000fffffffe R15: ffff93b8da3446c0 +[   49.828890] FS:  00007ffbedffb700(0000) GS:ffff93b927880000(0000) knlGS:0000000000000000 +[   49.830725] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[   49.832359] CR2: 0000000000000088 CR3: 00000005e3f74006 CR4: 00000000003606a0 +[   49.834085] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[   49.835792] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + +Cc: +Fixes: a6c606551141 ("ovl: redirect on rename-dir") +Signed-off-by: Liangyan +Reviewed-by: Joseph Qi +Suggested-by: Al Viro +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman +--- + fs/overlayfs/dir.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/overlayfs/dir.c ++++ b/fs/overlayfs/dir.c +@@ -850,8 +850,8 @@ static char *ovl_get_redirect(struct den + + buflen -= thislen; + memcpy(&buf[buflen], name, thislen); +- tmp = dget_dlock(d->d_parent); + spin_unlock(&d->d_lock); ++ tmp = dget_parent(d); + + dput(d); + d = tmp; diff --git a/queue-4.14/series b/queue-4.14/series index 2686b93357f..d195f6b283c 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -7,3 +7,11 @@ net-lapb-copy-the-skb-before-sending-a-packet.patch objtool-support-clang-non-section-symbols-in-orc-generation.patch elfcore-fix-building-with-clang.patch ipv4-fix-race-condition-between-route-lookup-and-invalidation.patch +usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch +usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch +usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch +ovl-fix-dentry-leak-in-ovl_get_redirect.patch +mac80211-fix-station-rate-table-updates-on-assoc.patch +kretprobe-avoid-re-registration-of-the-same-kretprobe-earlier.patch +xhci-fix-bounce-buffer-usage-for-non-sg-list-case.patch +cifs-report-error-instead-of-invalid-when-revalidating-a-dentry-fails.patch diff --git a/queue-4.14/usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch b/queue-4.14/usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch new file mode 100644 index 00000000000..673ba37d3f5 --- /dev/null +++ b/queue-4.14/usb-dwc2-fix-endpoint-direction-check-in-ep_from_windex.patch @@ -0,0 +1,74 @@ +From f670e9f9c8cac716c3506c6bac9e997b27ad441a Mon Sep 17 00:00:00 2001 +From: Heiko Stuebner +Date: Wed, 27 Jan 2021 11:39:19 +0100 +Subject: usb: dwc2: Fix endpoint direction check in ep_from_windex + +From: Heiko Stuebner + +commit f670e9f9c8cac716c3506c6bac9e997b27ad441a upstream. + +dwc2_hsotg_process_req_status uses ep_from_windex() to retrieve +the endpoint for the index provided in the wIndex request param. + +In a test-case with a rndis gadget running and sending a malformed +packet to it like: + dev.ctrl_transfer( + 0x82, # bmRequestType + 0x00, # bRequest + 0x0000, # wValue + 0x0001, # wIndex + 0x00 # wLength + ) +it is possible to cause a crash: + +[ 217.533022] dwc2 ff300000.usb: dwc2_hsotg_process_req_status: USB_REQ_GET_STATUS +[ 217.559003] Unable to handle kernel read from unreadable memory at virtual address 0000000000000088 +... +[ 218.313189] Call trace: +[ 218.330217] ep_from_windex+0x3c/0x54 +[ 218.348565] usb_gadget_giveback_request+0x10/0x20 +[ 218.368056] dwc2_hsotg_complete_request+0x144/0x184 + +This happens because ep_from_windex wants to compare the endpoint +direction even if index_to_ep() didn't return an endpoint due to +the direction not matching. + +The fix is easy insofar that the actual direction check is already +happening when calling index_to_ep() which will return NULL if there +is no endpoint for the targeted direction, so the offending check +can go away completely. + +Fixes: c6f5c050e2a7 ("usb: dwc2: gadget: add bi-directional endpoint support") +Cc: stable@vger.kernel.org +Reported-by: Gerhard Klostermeier +Signed-off-by: Heiko Stuebner +Link: https://lore.kernel.org/r/20210127103919.58215-1-heiko@sntech.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc2/gadget.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/drivers/usb/dwc2/gadget.c ++++ b/drivers/usb/dwc2/gadget.c +@@ -1470,7 +1470,6 @@ static void dwc2_hsotg_complete_oursetup + static struct dwc2_hsotg_ep *ep_from_windex(struct dwc2_hsotg *hsotg, + u32 windex) + { +- struct dwc2_hsotg_ep *ep; + int dir = (windex & USB_DIR_IN) ? 1 : 0; + int idx = windex & 0x7F; + +@@ -1480,12 +1479,7 @@ static struct dwc2_hsotg_ep *ep_from_win + if (idx > hsotg->num_of_eps) + return NULL; + +- ep = index_to_ep(hsotg, idx, dir); +- +- if (idx && ep->dir_in != dir) +- return NULL; +- +- return ep; ++ return index_to_ep(hsotg, idx, dir); + } + + /** diff --git a/queue-4.14/usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch b/queue-4.14/usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch new file mode 100644 index 00000000000..3fc4c45508c --- /dev/null +++ b/queue-4.14/usb-gadget-legacy-fix-an-error-code-in-eth_bind.patch @@ -0,0 +1,35 @@ +From 3e1f4a2e1184ae6ad7f4caf682ced9554141a0f4 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 28 Jan 2021 12:33:42 +0300 +Subject: USB: gadget: legacy: fix an error code in eth_bind() + +From: Dan Carpenter + +commit 3e1f4a2e1184ae6ad7f4caf682ced9554141a0f4 upstream. + +This code should return -ENOMEM if the allocation fails but it currently +returns success. + +Fixes: 9b95236eebdb ("usb: gadget: ether: allocate and init otg descriptor by otg capabilities") +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/YBKE9rqVuJEOUWpW@mwanda +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/legacy/ether.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/legacy/ether.c ++++ b/drivers/usb/gadget/legacy/ether.c +@@ -407,8 +407,10 @@ static int eth_bind(struct usb_composite + struct usb_descriptor_header *usb_desc; + + usb_desc = usb_otg_descriptor_alloc(gadget); +- if (!usb_desc) ++ if (!usb_desc) { ++ status = -ENOMEM; + goto fail1; ++ } + usb_otg_descriptor_init(gadget, usb_desc); + otg_desc[0] = usb_desc; + otg_desc[1] = NULL; diff --git a/queue-4.14/usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch b/queue-4.14/usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch new file mode 100644 index 00000000000..01e5d69d009 --- /dev/null +++ b/queue-4.14/usb-usblp-don-t-call-usb_set_interface-if-there-s-a-single-alt.patch @@ -0,0 +1,51 @@ +From d8c6edfa3f4ee0d45d7ce5ef18d1245b78774b9d Mon Sep 17 00:00:00 2001 +From: Jeremy Figgins +Date: Sat, 23 Jan 2021 18:21:36 -0600 +Subject: USB: usblp: don't call usb_set_interface if there's a single alt + +From: Jeremy Figgins + +commit d8c6edfa3f4ee0d45d7ce5ef18d1245b78774b9d upstream. + +Some devices, such as the Winbond Electronics Corp. Virtual Com Port +(Vendor=0416, ProdId=5011), lockup when usb_set_interface() or +usb_clear_halt() are called. This device has only a single +altsetting, so it should not be necessary to call usb_set_interface(). + +Acked-by: Pete Zaitcev +Signed-off-by: Jeremy Figgins +Link: https://lore.kernel.org/r/YAy9kJhM/rG8EQXC@watson +Cc: stable +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/class/usblp.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +--- a/drivers/usb/class/usblp.c ++++ b/drivers/usb/class/usblp.c +@@ -1340,14 +1340,17 @@ static int usblp_set_protocol(struct usb + if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL) + return -EINVAL; + +- alts = usblp->protocol[protocol].alt_setting; +- if (alts < 0) +- return -EINVAL; +- r = usb_set_interface(usblp->dev, usblp->ifnum, alts); +- if (r < 0) { +- printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n", +- alts, usblp->ifnum); +- return r; ++ /* Don't unnecessarily set the interface if there's a single alt. */ ++ if (usblp->intf->num_altsetting > 1) { ++ alts = usblp->protocol[protocol].alt_setting; ++ if (alts < 0) ++ return -EINVAL; ++ r = usb_set_interface(usblp->dev, usblp->ifnum, alts); ++ if (r < 0) { ++ printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n", ++ alts, usblp->ifnum); ++ return r; ++ } + } + + usblp->bidir = (usblp->protocol[protocol].epread != NULL); diff --git a/queue-4.14/xhci-fix-bounce-buffer-usage-for-non-sg-list-case.patch b/queue-4.14/xhci-fix-bounce-buffer-usage-for-non-sg-list-case.patch new file mode 100644 index 00000000000..4a46a69e224 --- /dev/null +++ b/queue-4.14/xhci-fix-bounce-buffer-usage-for-non-sg-list-case.patch @@ -0,0 +1,82 @@ +From d4a610635400ccc382792f6be69427078541c678 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Wed, 3 Feb 2021 13:37:02 +0200 +Subject: xhci: fix bounce buffer usage for non-sg list case + +From: Mathias Nyman + +commit d4a610635400ccc382792f6be69427078541c678 upstream. + +xhci driver may in some special cases need to copy small amounts +of payload data to a bounce buffer in order to meet the boundary +and alignment restrictions set by the xHCI specification. + +In the majority of these cases the data is in a sg list, and +driver incorrectly assumed data is always in urb->sg when using +the bounce buffer. + +If data instead is contiguous, and in urb->transfer_buffer, we may still +need to bounce buffer a small part if data starts very close (less than +packet size) to a 64k boundary. + +Check if sg list is used before copying data to/from it. + +Fixes: f9c589e142d0 ("xhci: TD-fragment, align the unsplittable case with a bounce buffer") +Cc: stable@vger.kernel.org +Reported-by: Andreas Hartmann +Tested-by: Andreas Hartmann +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20210203113702.436762-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci-ring.c | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -681,11 +681,16 @@ static void xhci_unmap_td_bounce_buffer( + dma_unmap_single(dev, seg->bounce_dma, ring->bounce_buf_len, + DMA_FROM_DEVICE); + /* for in tranfers we need to copy the data from bounce to sg */ +- len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf, +- seg->bounce_len, seg->bounce_offs); +- if (len != seg->bounce_len) +- xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != %d\n", +- len, seg->bounce_len); ++ if (urb->num_sgs) { ++ len = sg_pcopy_from_buffer(urb->sg, urb->num_sgs, seg->bounce_buf, ++ seg->bounce_len, seg->bounce_offs); ++ if (len != seg->bounce_len) ++ xhci_warn(xhci, "WARN Wrong bounce buffer read length: %zu != %d\n", ++ len, seg->bounce_len); ++ } else { ++ memcpy(urb->transfer_buffer + seg->bounce_offs, seg->bounce_buf, ++ seg->bounce_len); ++ } + seg->bounce_len = 0; + seg->bounce_offs = 0; + } +@@ -3252,12 +3257,16 @@ static int xhci_align_td(struct xhci_hcd + + /* create a max max_pkt sized bounce buffer pointed to by last trb */ + if (usb_urb_dir_out(urb)) { +- len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs, +- seg->bounce_buf, new_buff_len, enqd_len); +- if (len != new_buff_len) +- xhci_warn(xhci, +- "WARN Wrong bounce buffer write length: %zu != %d\n", +- len, new_buff_len); ++ if (urb->num_sgs) { ++ len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs, ++ seg->bounce_buf, new_buff_len, enqd_len); ++ if (len != new_buff_len) ++ xhci_warn(xhci, "WARN Wrong bounce buffer write length: %zu != %d\n", ++ len, new_buff_len); ++ } else { ++ memcpy(seg->bounce_buf, urb->transfer_buffer + enqd_len, new_buff_len); ++ } ++ + seg->bounce_dma = dma_map_single(dev, seg->bounce_buf, + max_pkt, DMA_TO_DEVICE); + } else { -- 2.47.3