From 665c9acf20a18782927a2ff9960c2e89a252cf4e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 5 Mar 2022 13:28:36 +0100 Subject: [PATCH] 4.9-stable patches added patches: net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch --- ...ble-entries-for-unregistered-devices.patch | 103 ++++++++++++++++++ queue-4.9/series | 1 + 2 files changed, 104 insertions(+) create mode 100644 queue-4.9/net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch diff --git a/queue-4.9/net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch b/queue-4.9/net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch new file mode 100644 index 00000000000..d57e5f3dd99 --- /dev/null +++ b/queue-4.9/net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch @@ -0,0 +1,103 @@ +From 91b0383fef06f20b847fa9e4f0e3054ead0b1a1b Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Thu, 24 Feb 2022 18:01:54 +0200 +Subject: net: dcb: flush lingering app table entries for unregistered devices + +From: Vladimir Oltean + +commit 91b0383fef06f20b847fa9e4f0e3054ead0b1a1b upstream. + +If I'm not mistaken (and I don't think I am), the way in which the +dcbnl_ops work is that drivers call dcb_ieee_setapp() and this populates +the application table with dynamically allocated struct dcb_app_type +entries that are kept in the module-global dcb_app_list. + +However, nobody keeps exact track of these entries, and although +dcb_ieee_delapp() is supposed to remove them, nobody does so when the +interface goes away (example: driver unbinds from device). So the +dcb_app_list will contain lingering entries with an ifindex that no +longer matches any device in dcb_app_lookup(). + +Reclaim the lost memory by listening for the NETDEV_UNREGISTER event and +flushing the app table entries of interfaces that are now gone. + +In fact something like this used to be done as part of the initial +commit (blamed below), but it was done in dcbnl_exit() -> dcb_flushapp(), +essentially at module_exit time. That became dead code after commit +7a6b6f515f77 ("DCB: fix kconfig option") which essentially merged +"tristate config DCB" and "bool config DCBNL" into a single "bool config +DCB", so net/dcb/dcbnl.c could not be built as a module anymore. + +Commit 36b9ad8084bd ("net/dcb: make dcbnl.c explicitly non-modular") +recognized this and deleted dcbnl_exit() and dcb_flushapp() altogether, +leaving us with the version we have today. + +Since flushing application table entries can and should be done as soon +as the netdevice disappears, fundamentally the commit that is to blame +is the one that introduced the design of this API. + +Fixes: 9ab933ab2cc8 ("dcbnl: add appliction tlv handlers") +Signed-off-by: Vladimir Oltean +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/dcb/dcbnl.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +--- a/net/dcb/dcbnl.c ++++ b/net/dcb/dcbnl.c +@@ -1938,10 +1938,54 @@ int dcb_ieee_delapp(struct net_device *d + } + EXPORT_SYMBOL(dcb_ieee_delapp); + ++static void dcbnl_flush_dev(struct net_device *dev) ++{ ++ struct dcb_app_type *itr, *tmp; ++ ++ spin_lock(&dcb_lock); ++ ++ list_for_each_entry_safe(itr, tmp, &dcb_app_list, list) { ++ if (itr->ifindex == dev->ifindex) { ++ list_del(&itr->list); ++ kfree(itr); ++ } ++ } ++ ++ spin_unlock(&dcb_lock); ++} ++ ++static int dcbnl_netdevice_event(struct notifier_block *nb, ++ unsigned long event, void *ptr) ++{ ++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); ++ ++ switch (event) { ++ case NETDEV_UNREGISTER: ++ if (!dev->dcbnl_ops) ++ return NOTIFY_DONE; ++ ++ dcbnl_flush_dev(dev); ++ ++ return NOTIFY_OK; ++ default: ++ return NOTIFY_DONE; ++ } ++} ++ ++static struct notifier_block dcbnl_nb __read_mostly = { ++ .notifier_call = dcbnl_netdevice_event, ++}; ++ + static int __init dcbnl_init(void) + { ++ int err; ++ + INIT_LIST_HEAD(&dcb_app_list); + ++ err = register_netdevice_notifier(&dcbnl_nb); ++ if (err) ++ return err; ++ + rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, NULL); + rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, NULL); + diff --git a/queue-4.9/series b/queue-4.9/series index ec1d1f47832..044d17b20ae 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -13,3 +13,4 @@ asoc-ops-shift-tested-values-in-snd_soc_put_volsw-by-min.patch xfrm-fix-mtu-regression.patch netfilter-nf_queue-don-t-assume-sk-is-full-socket.patch netfilter-nf_queue-fix-possible-use-after-free.patch +net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch -- 2.47.2