From: Greg Kroah-Hartman Date: Tue, 1 Dec 2020 08:35:32 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.4.247~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7e208f8ffeb2df0c94c47628e9f416af78e829e7;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: usb-core-fix-regression-in-hercules-audio-card.patch x86-resctrl-add-necessary-kernfs_put-calls-to-prevent-refcount-leak.patch x86-resctrl-remove-superfluous-kernfs_get-calls-to-prevent-refcount-leak.patch --- diff --git a/queue-4.19/series b/queue-4.19/series index 04f775e1640..0ad72b0fbaa 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -53,3 +53,6 @@ usb-gadget-f_midi-fix-memleak-in-f_midi_alloc.patch usb-quirks-add-usb_quirk_disconnect_suspend-quirk-for-lenovo-a630z-tio-built-in-usb-audio-card.patch usb-gadget-fix-memleak-in-gadgetfs_fill_super.patch x86-speculation-fix-prctl-when-spectre_v2_user-seccomp-prctl-ibpb.patch +x86-resctrl-remove-superfluous-kernfs_get-calls-to-prevent-refcount-leak.patch +x86-resctrl-add-necessary-kernfs_put-calls-to-prevent-refcount-leak.patch +usb-core-fix-regression-in-hercules-audio-card.patch diff --git a/queue-4.19/usb-core-fix-regression-in-hercules-audio-card.patch b/queue-4.19/usb-core-fix-regression-in-hercules-audio-card.patch new file mode 100644 index 00000000000..ba734f43f73 --- /dev/null +++ b/queue-4.19/usb-core-fix-regression-in-hercules-audio-card.patch @@ -0,0 +1,57 @@ +From foo@baz Tue Dec 1 09:30:03 AM CET 2020 +From: Alan Stern +Date: Thu, 19 Nov 2020 12:00:40 -0500 +Subject: USB: core: Fix regression in Hercules audio card + +From: Alan Stern + +commit 184eead057cc7e803558269babc1f2cfb9113ad1 upstream + +Commit 3e4f8e21c4f2 ("USB: core: fix check for duplicate endpoints") +aimed to make the USB stack more reliable by detecting and skipping +over endpoints that are duplicated between interfaces. This caused a +regression for a Hercules audio card (reported as Bugzilla #208357), +which contains such non-compliant duplications. Although the +duplications are harmless, skipping the valid endpoints prevented the +device from working. + +This patch fixes the regression by adding ENDPOINT_IGNORE quirks for +the Hercules card, telling the kernel to ignore the invalid duplicate +endpoints and thereby allowing the valid endpoints to be used as +intended. + +Fixes: 3e4f8e21c4f2 ("USB: core: fix check for duplicate endpoints") +CC: +Reported-by: Alexander Chalikiopoulos +Signed-off-by: Alan Stern +Link: https://lore.kernel.org/r/20201119170040.GA576844@rowland.harvard.edu +Signed-off-by: Greg Kroah-Hartman +[sudip: use usb_endpoint_blacklist and USB_QUIRK_ENDPOINT_BLACKLIST] +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/core/quirks.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -348,6 +348,10 @@ static const struct usb_device_id usb_qu + /* Guillemot Webcam Hercules Dualpix Exchange*/ + { USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME }, + ++ /* Guillemot Hercules DJ Console audio card (BZ 208357) */ ++ { USB_DEVICE(0x06f8, 0xb000), .driver_info = ++ USB_QUIRK_ENDPOINT_BLACKLIST }, ++ + /* Midiman M-Audio Keystation 88es */ + { USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME }, + +@@ -525,6 +529,8 @@ 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(0x06f8, 0xb000, 5), .driver_info = 0x01 }, ++ { USB_DEVICE_INTERFACE_NUMBER(0x06f8, 0xb000, 5), .driver_info = 0x81 }, + { USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0202, 1), .driver_info = 0x85 }, + { USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0208, 1), .driver_info = 0x85 }, + { } diff --git a/queue-4.19/x86-resctrl-add-necessary-kernfs_put-calls-to-prevent-refcount-leak.patch b/queue-4.19/x86-resctrl-add-necessary-kernfs_put-calls-to-prevent-refcount-leak.patch new file mode 100644 index 00000000000..02f48d15598 --- /dev/null +++ b/queue-4.19/x86-resctrl-add-necessary-kernfs_put-calls-to-prevent-refcount-leak.patch @@ -0,0 +1,167 @@ +From 758999246965eeb8b253d47e72f7bfe508804b16 Mon Sep 17 00:00:00 2001 +From: Xiaochen Shen +Date: Sat, 31 Oct 2020 03:11:28 +0800 +Subject: x86/resctrl: Add necessary kernfs_put() calls to prevent refcount leak + +From: Xiaochen Shen + +commit 758999246965eeb8b253d47e72f7bfe508804b16 upstream. + +On resource group creation via a mkdir an extra kernfs_node reference is +obtained by kernfs_get() to ensure that the rdtgroup structure remains +accessible for the rdtgroup_kn_unlock() calls where it is removed on +deletion. Currently the extra kernfs_node reference count is only +dropped by kernfs_put() in rdtgroup_kn_unlock() while the rdtgroup +structure is removed in a few other locations that lack the matching +reference drop. + +In call paths of rmdir and umount, when a control group is removed, +kernfs_remove() is called to remove the whole kernfs nodes tree of the +control group (including the kernfs nodes trees of all child monitoring +groups), and then rdtgroup structure is freed by kfree(). The rdtgroup +structures of all child monitoring groups under the control group are +freed by kfree() in free_all_child_rdtgrp(). + +Before calling kfree() to free the rdtgroup structures, the kernfs node +of the control group itself as well as the kernfs nodes of all child +monitoring groups still take the extra references which will never be +dropped to 0 and the kernfs nodes will never be freed. It leads to +reference count leak and kernfs_node_cache memory leak. + +For example, reference count leak is observed in these two cases: + (1) mount -t resctrl resctrl /sys/fs/resctrl + mkdir /sys/fs/resctrl/c1 + mkdir /sys/fs/resctrl/c1/mon_groups/m1 + umount /sys/fs/resctrl + + (2) mkdir /sys/fs/resctrl/c1 + mkdir /sys/fs/resctrl/c1/mon_groups/m1 + rmdir /sys/fs/resctrl/c1 + +The same reference count leak issue also exists in the error exit paths +of mkdir in mkdir_rdt_prepare() and rdtgroup_mkdir_ctrl_mon(). + +Fix this issue by following changes to make sure the extra kernfs_node +reference on rdtgroup is dropped before freeing the rdtgroup structure. + (1) Introduce rdtgroup removal helper rdtgroup_remove() to wrap up + kernfs_put() and kfree(). + + (2) Call rdtgroup_remove() in rdtgroup removal path where the rdtgroup + structure is about to be freed by kfree(). + + (3) Call rdtgroup_remove() or kernfs_put() as appropriate in the error + exit paths of mkdir where an extra reference is taken by kernfs_get(). + +Backporting notes: + +Since upstream commit fa7d949337cc ("x86/resctrl: Rename and move rdt +files to a separate directory"), the file +arch/x86/kernel/cpu/intel_rdt_rdtgroup.c has been renamed and moved to +arch/x86/kernel/cpu/resctrl/rdtgroup.c. +Apply the change against file arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +in older stable trees. + +Fixes: f3cbeacaa06e ("x86/intel_rdt/cqm: Add rmdir support") +Fixes: e02737d5b826 ("x86/intel_rdt: Add tasks files") +Fixes: 60cf5e101fd4 ("x86/intel_rdt: Add mkdir to resctrl file system") +Reported-by: Willem de Bruijn +Signed-off-by: Xiaochen Shen +Signed-off-by: Borislav Petkov +Reviewed-by: Reinette Chatre +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/1604085088-31707-1-git-send-email-xiaochen.shen@intel.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 32 ++++++++++++++++++++++++------- + 1 file changed, 25 insertions(+), 7 deletions(-) + +--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c ++++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +@@ -515,6 +515,24 @@ unlock: + return ret ?: nbytes; + } + ++/** ++ * rdtgroup_remove - the helper to remove resource group safely ++ * @rdtgrp: resource group to remove ++ * ++ * On resource group creation via a mkdir, an extra kernfs_node reference is ++ * taken to ensure that the rdtgroup structure remains accessible for the ++ * rdtgroup_kn_unlock() calls where it is removed. ++ * ++ * Drop the extra reference here, then free the rdtgroup structure. ++ * ++ * Return: void ++ */ ++static void rdtgroup_remove(struct rdtgroup *rdtgrp) ++{ ++ kernfs_put(rdtgrp->kn); ++ kfree(rdtgrp); ++} ++ + struct task_move_callback { + struct callback_head work; + struct rdtgroup *rdtgrp; +@@ -537,7 +555,7 @@ static void move_myself(struct callback_ + (rdtgrp->flags & RDT_DELETED)) { + current->closid = 0; + current->rmid = 0; +- kfree(rdtgrp); ++ rdtgroup_remove(rdtgrp); + } + + preempt_disable(); +@@ -1959,8 +1977,7 @@ void rdtgroup_kn_unlock(struct kernfs_no + rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) + rdtgroup_pseudo_lock_remove(rdtgrp); + kernfs_unbreak_active_protection(kn); +- kernfs_put(rdtgrp->kn); +- kfree(rdtgrp); ++ rdtgroup_remove(rdtgrp); + } else { + kernfs_unbreak_active_protection(kn); + } +@@ -2169,7 +2186,7 @@ static void free_all_child_rdtgrp(struct + if (atomic_read(&sentry->waitcount) != 0) + sentry->flags = RDT_DELETED; + else +- kfree(sentry); ++ rdtgroup_remove(sentry); + } + } + +@@ -2211,7 +2228,7 @@ static void rmdir_all_sub(void) + if (atomic_read(&rdtgrp->waitcount) != 0) + rdtgrp->flags = RDT_DELETED; + else +- kfree(rdtgrp); ++ rdtgroup_remove(rdtgrp); + } + /* Notify online CPUs to update per cpu storage and PQR_ASSOC MSR */ + update_closid_rmid(cpu_online_mask, &rdtgroup_default); +@@ -2602,7 +2619,7 @@ static int mkdir_rdt_prepare(struct kern + * kernfs_remove() will drop the reference count on "kn" which + * will free it. But we still need it to stick around for the + * rdtgroup_kn_unlock(kn) call. Take one extra reference here, +- * which will be dropped inside rdtgroup_kn_unlock(). ++ * which will be dropped by kernfs_put() in rdtgroup_remove(). + */ + kernfs_get(kn); + +@@ -2643,6 +2660,7 @@ static int mkdir_rdt_prepare(struct kern + out_idfree: + free_rmid(rdtgrp->mon.rmid); + out_destroy: ++ kernfs_put(rdtgrp->kn); + kernfs_remove(rdtgrp->kn); + out_free_rgrp: + kfree(rdtgrp); +@@ -2655,7 +2673,7 @@ static void mkdir_rdt_prepare_clean(stru + { + kernfs_remove(rgrp->kn); + free_rmid(rgrp->mon.rmid); +- kfree(rgrp); ++ rdtgroup_remove(rgrp); + } + + /* diff --git a/queue-4.19/x86-resctrl-remove-superfluous-kernfs_get-calls-to-prevent-refcount-leak.patch b/queue-4.19/x86-resctrl-remove-superfluous-kernfs_get-calls-to-prevent-refcount-leak.patch new file mode 100644 index 00000000000..a9cb3fca1a8 --- /dev/null +++ b/queue-4.19/x86-resctrl-remove-superfluous-kernfs_get-calls-to-prevent-refcount-leak.patch @@ -0,0 +1,176 @@ +From fd8d9db3559a29fd737bcdb7c4fcbe1940caae34 Mon Sep 17 00:00:00 2001 +From: Xiaochen Shen +Date: Sat, 31 Oct 2020 03:10:53 +0800 +Subject: x86/resctrl: Remove superfluous kernfs_get() calls to prevent refcount leak + +From: Xiaochen Shen + +commit fd8d9db3559a29fd737bcdb7c4fcbe1940caae34 upstream. + +Willem reported growing of kernfs_node_cache entries in slabtop when +repeatedly creating and removing resctrl subdirectories as well as when +repeatedly mounting and unmounting the resctrl filesystem. + +On resource group (control as well as monitoring) creation via a mkdir +an extra kernfs_node reference is obtained to ensure that the rdtgroup +structure remains accessible for the rdtgroup_kn_unlock() calls where it +is removed on deletion. The kernfs_node reference count is dropped by +kernfs_put() in rdtgroup_kn_unlock(). + +With the above explaining the need for one kernfs_get()/kernfs_put() +pair in resctrl there are more places where a kernfs_node reference is +obtained without a corresponding release. The excessive amount of +reference count on kernfs nodes will never be dropped to 0 and the +kernfs nodes will never be freed in the call paths of rmdir and umount. +It leads to reference count leak and kernfs_node_cache memory leak. + +Remove the superfluous kernfs_get() calls and expand the existing +comments surrounding the remaining kernfs_get()/kernfs_put() pair that +remains in use. + +Superfluous kernfs_get() calls are removed from two areas: + + (1) In call paths of mount and mkdir, when kernfs nodes for "info", + "mon_groups" and "mon_data" directories and sub-directories are + created, the reference count of newly created kernfs node is set to 1. + But after kernfs_create_dir() returns, superfluous kernfs_get() are + called to take an additional reference. + + (2) kernfs_get() calls in rmdir call paths. + +Backporting notes: + +Since upstream commit fa7d949337cc ("x86/resctrl: Rename and move rdt +files to a separate directory"), the file +arch/x86/kernel/cpu/intel_rdt_rdtgroup.c has been renamed and moved to +arch/x86/kernel/cpu/resctrl/rdtgroup.c. +Apply the change against file arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +for older stable trees. + +Fixes: 17eafd076291 ("x86/intel_rdt: Split resource group removal in two") +Fixes: 4af4a88e0c92 ("x86/intel_rdt/cqm: Add mount,umount support") +Fixes: f3cbeacaa06e ("x86/intel_rdt/cqm: Add rmdir support") +Fixes: d89b7379015f ("x86/intel_rdt/cqm: Add mon_data") +Fixes: c7d9aac61311 ("x86/intel_rdt/cqm: Add mkdir support for RDT monitoring") +Fixes: 5dc1d5c6bac2 ("x86/intel_rdt: Simplify info and base file lists") +Fixes: 60cf5e101fd4 ("x86/intel_rdt: Add mkdir to resctrl file system") +Fixes: 4e978d06dedb ("x86/intel_rdt: Add "info" files to resctrl file system") +Reported-by: Willem de Bruijn +Signed-off-by: Xiaochen Shen +Signed-off-by: Borislav Petkov +Reviewed-by: Reinette Chatre +Tested-by: Willem de Bruijn +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/1604085053-31639-1-git-send-email-xiaochen.shen@intel.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/intel_rdt_rdtgroup.c | 35 +------------------------------ + 1 file changed, 2 insertions(+), 33 deletions(-) + +--- a/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c ++++ b/arch/x86/kernel/cpu/intel_rdt_rdtgroup.c +@@ -1626,7 +1626,6 @@ static int rdtgroup_mkdir_info_resdir(st + if (IS_ERR(kn_subdir)) + return PTR_ERR(kn_subdir); + +- kernfs_get(kn_subdir); + ret = rdtgroup_kn_set_ugid(kn_subdir); + if (ret) + return ret; +@@ -1649,7 +1648,6 @@ static int rdtgroup_create_info_dir(stru + kn_info = kernfs_create_dir(parent_kn, "info", parent_kn->mode, NULL); + if (IS_ERR(kn_info)) + return PTR_ERR(kn_info); +- kernfs_get(kn_info); + + ret = rdtgroup_add_files(kn_info, RF_TOP_INFO); + if (ret) +@@ -1670,12 +1668,6 @@ static int rdtgroup_create_info_dir(stru + goto out_destroy; + } + +- /* +- * This extra ref will be put in kernfs_remove() and guarantees +- * that @rdtgrp->kn is always accessible. +- */ +- kernfs_get(kn_info); +- + ret = rdtgroup_kn_set_ugid(kn_info); + if (ret) + goto out_destroy; +@@ -1704,12 +1696,6 @@ mongroup_create_dir(struct kernfs_node * + if (dest_kn) + *dest_kn = kn; + +- /* +- * This extra ref will be put in kernfs_remove() and guarantees +- * that @rdtgrp->kn is always accessible. +- */ +- kernfs_get(kn); +- + ret = rdtgroup_kn_set_ugid(kn); + if (ret) + goto out_destroy; +@@ -2025,7 +2011,6 @@ static struct dentry *rdt_mount(struct f + dentry = ERR_PTR(ret); + goto out_info; + } +- kernfs_get(kn_mongrp); + + ret = mkdir_mondata_all(rdtgroup_default.kn, + &rdtgroup_default, &kn_mondata); +@@ -2033,7 +2018,6 @@ static struct dentry *rdt_mount(struct f + dentry = ERR_PTR(ret); + goto out_mongrp; + } +- kernfs_get(kn_mondata); + rdtgroup_default.mon.mon_data_kn = kn_mondata; + } + +@@ -2326,11 +2310,6 @@ static int mkdir_mondata_subdir(struct k + if (IS_ERR(kn)) + return PTR_ERR(kn); + +- /* +- * This extra ref will be put in kernfs_remove() and guarantees +- * that kn is always accessible. +- */ +- kernfs_get(kn); + ret = rdtgroup_kn_set_ugid(kn); + if (ret) + goto out_destroy; +@@ -2622,8 +2601,8 @@ static int mkdir_rdt_prepare(struct kern + /* + * kernfs_remove() will drop the reference count on "kn" which + * will free it. But we still need it to stick around for the +- * rdtgroup_kn_unlock(kn} call below. Take one extra reference +- * here, which will be dropped inside rdtgroup_kn_unlock(). ++ * rdtgroup_kn_unlock(kn) call. Take one extra reference here, ++ * which will be dropped inside rdtgroup_kn_unlock(). + */ + kernfs_get(kn); + +@@ -2838,11 +2817,6 @@ static int rdtgroup_rmdir_mon(struct ker + WARN_ON(list_empty(&prdtgrp->mon.crdtgrp_list)); + list_del(&rdtgrp->mon.crdtgrp_list); + +- /* +- * one extra hold on this, will drop when we kfree(rdtgrp) +- * in rdtgroup_kn_unlock() +- */ +- kernfs_get(kn); + kernfs_remove(rdtgrp->kn); + + return 0; +@@ -2854,11 +2828,6 @@ static int rdtgroup_ctrl_remove(struct k + rdtgrp->flags = RDT_DELETED; + list_del(&rdtgrp->rdtgroup_list); + +- /* +- * one extra hold on this, will drop when we kfree(rdtgrp) +- * in rdtgroup_kn_unlock() +- */ +- kernfs_get(kn); + kernfs_remove(rdtgrp->kn); + return 0; + }