]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Mar 2022 12:29:04 +0000 (13:29 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Mar 2022 12:29:04 +0000 (13:29 +0100)
added patches:
batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch
batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch
batman-adv-request-iflink-once-in-batadv_get_real_netdevice.patch
net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch
net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch
net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch

queue-4.19/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch [new file with mode: 0644]
queue-4.19/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch [new file with mode: 0644]
queue-4.19/batman-adv-request-iflink-once-in-batadv_get_real_netdevice.patch [new file with mode: 0644]
queue-4.19/net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch [new file with mode: 0644]
queue-4.19/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch [new file with mode: 0644]
queue-4.19/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch b/queue-4.19/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch
new file mode 100644 (file)
index 0000000..f3876e5
--- /dev/null
@@ -0,0 +1,95 @@
+From 6c1f41afc1dbe59d9d3c8bb0d80b749c119aa334 Mon Sep 17 00:00:00 2001
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sun, 27 Feb 2022 23:23:49 +0100
+Subject: batman-adv: Don't expect inter-netns unique iflink indices
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 6c1f41afc1dbe59d9d3c8bb0d80b749c119aa334 upstream.
+
+The ifindex doesn't have to be unique for multiple network namespaces on
+the same machine.
+
+  $ ip netns add test1
+  $ ip -net test1 link add dummy1 type dummy
+  $ ip netns add test2
+  $ ip -net test2 link add dummy2 type dummy
+
+  $ ip -net test1 link show dev dummy1
+  6: dummy1: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
+      link/ether 96:81:55:1e:dd:85 brd ff:ff:ff:ff:ff:ff
+  $ ip -net test2 link show dev dummy2
+  6: dummy2: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
+      link/ether 5a:3c:af:35:07:c3 brd ff:ff:ff:ff:ff:ff
+
+But the batman-adv code to walk through the various layers of virtual
+interfaces uses this assumption because dev_get_iflink handles it
+internally and doesn't return the actual netns of the iflink. And
+dev_get_iflink only documents the situation where ifindex == iflink for
+physical devices.
+
+But only checking for dev->netdev_ops->ndo_get_iflink is also not an option
+because ipoib_get_iflink implements it even when it sometimes returns an
+iflink != ifindex and sometimes iflink == ifindex. The caller must
+therefore make sure itself to check both netns and iflink + ifindex for
+equality. Only when they are equal, a "physical" interface was detected
+which should stop the traversal. On the other hand, vxcan_get_iflink can
+also return 0 in case there was currently no valid peer. In this case, it
+is still necessary to stop.
+
+Fixes: b7eddd0b3950 ("batman-adv: prevent using any virtual device created on batman-adv as hard-interface")
+Fixes: 5ed4a460a1d3 ("batman-adv: additional checks for virtual interfaces on top of WiFi")
+Reported-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/hard-interface.c |   19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -170,13 +170,15 @@ static bool batadv_is_on_batman_iface(co
+               return true;
+       iflink = dev_get_iflink(net_dev);
+-
+-      /* no more parents..stop recursion */
+-      if (iflink == 0 || iflink == net_dev->ifindex)
++      if (iflink == 0)
+               return false;
+       parent_net = batadv_getlink_net(net_dev, net);
++      /* iflink to itself, most likely physical device */
++      if (net == parent_net && iflink == net_dev->ifindex)
++              return false;
++
+       /* recurse over the parent device */
+       parent_dev = __dev_get_by_index((struct net *)parent_net, iflink);
+       /* if we got a NULL parent_dev there is something broken.. */
+@@ -236,8 +238,7 @@ static struct net_device *batadv_get_rea
+               return NULL;
+       iflink = dev_get_iflink(netdev);
+-
+-      if (netdev->ifindex == iflink) {
++      if (iflink == 0) {
+               dev_hold(netdev);
+               return netdev;
+       }
+@@ -248,6 +249,14 @@ static struct net_device *batadv_get_rea
+       net = dev_net(hard_iface->soft_iface);
+       real_net = batadv_getlink_net(netdev, net);
++
++      /* iflink to itself, most likely physical device */
++      if (net == real_net && netdev->ifindex == iflink) {
++              real_netdev = netdev;
++              dev_hold(real_netdev);
++              goto out;
++      }
++
+       real_netdev = dev_get_by_index(real_net, iflink);
+ out:
diff --git a/queue-4.19/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch b/queue-4.19/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch
new file mode 100644 (file)
index 0000000..c1ed8d4
--- /dev/null
@@ -0,0 +1,53 @@
+From 690bb6fb64f5dc7437317153902573ecad67593d Mon Sep 17 00:00:00 2001
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 28 Feb 2022 00:01:24 +0100
+Subject: batman-adv: Request iflink once in batadv-on-batadv check
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 690bb6fb64f5dc7437317153902573ecad67593d upstream.
+
+There is no need to call dev_get_iflink multiple times for the same
+net_device in batadv_is_on_batman_iface. And since some of the
+.ndo_get_iflink callbacks are dynamic (for example via RCUs like in
+vxcan_get_iflink), it could easily happen that the returned values are not
+stable. The pre-checks before __dev_get_by_index are then of course bogus.
+
+Fixes: b7eddd0b3950 ("batman-adv: prevent using any virtual device created on batman-adv as hard-interface")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/hard-interface.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -162,22 +162,23 @@ static bool batadv_is_on_batman_iface(co
+       struct net *net = dev_net(net_dev);
+       struct net_device *parent_dev;
+       struct net *parent_net;
++      int iflink;
+       bool ret;
+       /* check if this is a batman-adv mesh interface */
+       if (batadv_softif_is_valid(net_dev))
+               return true;
++      iflink = dev_get_iflink(net_dev);
++
+       /* no more parents..stop recursion */
+-      if (dev_get_iflink(net_dev) == 0 ||
+-          dev_get_iflink(net_dev) == net_dev->ifindex)
++      if (iflink == 0 || iflink == net_dev->ifindex)
+               return false;
+       parent_net = batadv_getlink_net(net_dev, net);
+       /* recurse over the parent device */
+-      parent_dev = __dev_get_by_index((struct net *)parent_net,
+-                                      dev_get_iflink(net_dev));
++      parent_dev = __dev_get_by_index((struct net *)parent_net, iflink);
+       /* if we got a NULL parent_dev there is something broken.. */
+       if (!parent_dev) {
+               pr_err("Cannot find parent device\n");
diff --git a/queue-4.19/batman-adv-request-iflink-once-in-batadv_get_real_netdevice.patch b/queue-4.19/batman-adv-request-iflink-once-in-batadv_get_real_netdevice.patch
new file mode 100644 (file)
index 0000000..f4cadc5
--- /dev/null
@@ -0,0 +1,55 @@
+From 6116ba09423f7d140f0460be6a1644dceaad00da Mon Sep 17 00:00:00 2001
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 28 Feb 2022 00:01:24 +0100
+Subject: batman-adv: Request iflink once in batadv_get_real_netdevice
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 6116ba09423f7d140f0460be6a1644dceaad00da upstream.
+
+There is no need to call dev_get_iflink multiple times for the same
+net_device in batadv_get_real_netdevice. And since some of the
+ndo_get_iflink callbacks are dynamic (for example via RCUs like in
+vxcan_get_iflink), it could easily happen that the returned values are not
+stable. The pre-checks before __dev_get_by_index are then of course bogus.
+
+Fixes: 5ed4a460a1d3 ("batman-adv: additional checks for virtual interfaces on top of WiFi")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/hard-interface.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -228,14 +228,16 @@ static struct net_device *batadv_get_rea
+       struct net_device *real_netdev = NULL;
+       struct net *real_net;
+       struct net *net;
+-      int ifindex;
++      int iflink;
+       ASSERT_RTNL();
+       if (!netdev)
+               return NULL;
+-      if (netdev->ifindex == dev_get_iflink(netdev)) {
++      iflink = dev_get_iflink(netdev);
++
++      if (netdev->ifindex == iflink) {
+               dev_hold(netdev);
+               return netdev;
+       }
+@@ -245,9 +247,8 @@ static struct net_device *batadv_get_rea
+               goto out;
+       net = dev_net(hard_iface->soft_iface);
+-      ifindex = dev_get_iflink(netdev);
+       real_net = batadv_getlink_net(netdev, net);
+-      real_netdev = dev_get_by_index(real_net, ifindex);
++      real_netdev = dev_get_by_index(real_net, iflink);
+ out:
+       if (hard_iface)
diff --git a/queue-4.19/net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch b/queue-4.19/net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch
new file mode 100644 (file)
index 0000000..5dbc2d4
--- /dev/null
@@ -0,0 +1,103 @@
+From 91b0383fef06f20b847fa9e4f0e3054ead0b1a1b Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Thu, 24 Feb 2022 18:01:54 +0200
+Subject: net: dcb: flush lingering app table entries for unregistered devices
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+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 <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/dcb/dcbnl.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+--- a/net/dcb/dcbnl.c
++++ b/net/dcb/dcbnl.c
+@@ -2054,10 +2054,54 @@ u8 dcb_ieee_getapp_default_prio_mask(con
+ }
+ EXPORT_SYMBOL(dcb_ieee_getapp_default_prio_mask);
++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, 0);
+       rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, 0);
diff --git a/queue-4.19/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch b/queue-4.19/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch
new file mode 100644 (file)
index 0000000..e07e70e
--- /dev/null
@@ -0,0 +1,40 @@
+From 4940a1fdf31c39f0806ac831cde333134862030b Mon Sep 17 00:00:00 2001
+From: "D. Wythe" <alibuda@linux.alibaba.com>
+Date: Wed, 2 Mar 2022 21:25:12 +0800
+Subject: net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error cause by server
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+commit 4940a1fdf31c39f0806ac831cde333134862030b upstream.
+
+The problem of SMC_CLC_DECL_ERR_REGRMB on the server is very clear.
+Based on the fact that whether a new SMC connection can be accepted or
+not depends on not only the limit of conn nums, but also the available
+entries of rtoken. Since the rtoken release is trigger by peer, while
+the conn nums is decrease by local, tons of thing can happen in this
+time difference.
+
+This only thing that needs to be mentioned is that now all connection
+creations are completely protected by smc_server_lgr_pending lock, it's
+enough to check only the available entries in rtokens_used_mask.
+
+Fixes: cd6851f30386 ("smc: remote memory buffers (RMBs)")
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/smc/smc_core.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/smc/smc_core.c
++++ b/net/smc/smc_core.c
+@@ -609,7 +609,8 @@ int smc_conn_create(struct smc_sock *smc
+                   !lgr->sync_err &&
+                   lgr->vlan_id == vlan_id &&
+                   (role == SMC_CLNT ||
+-                   lgr->conns_num < SMC_RMBS_PER_LGR_MAX)) {
++                  (lgr->conns_num < SMC_RMBS_PER_LGR_MAX &&
++                    !bitmap_full(lgr->rtokens_used_mask, SMC_RMBS_PER_LGR_MAX)))) {
+                       /* link group found */
+                       local_contact = SMC_REUSE_CONTACT;
+                       conn->lgr = lgr;
diff --git a/queue-4.19/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch b/queue-4.19/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch
new file mode 100644 (file)
index 0000000..a7e0751
--- /dev/null
@@ -0,0 +1,47 @@
+From 0537f0a2151375dcf90c1bbfda6a0aaf57164e89 Mon Sep 17 00:00:00 2001
+From: "D. Wythe" <alibuda@linux.alibaba.com>
+Date: Wed, 2 Mar 2022 21:25:11 +0800
+Subject: net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error generated by client
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+commit 0537f0a2151375dcf90c1bbfda6a0aaf57164e89 upstream.
+
+The main reason for this unexpected SMC_CLC_DECL_ERR_REGRMB in client
+dues to following execution sequence:
+
+Server Conn A:           Server Conn B:                        Client Conn B:
+
+smc_lgr_unregister_conn
+                        smc_lgr_register_conn
+                        smc_clc_send_accept     ->
+                                                        smc_rtoken_add
+smcr_buf_unuse
+               ->              Client Conn A:
+                               smc_rtoken_delete
+
+smc_lgr_unregister_conn() makes current link available to assigned to new
+incoming connection, while smcr_buf_unuse() has not executed yet, which
+means that smc_rtoken_add may fail because of insufficient rtoken_entry,
+reversing their execution order will avoid this problem.
+
+Fixes: 3e034725c0d8 ("net/smc: common functions for RMBs and send buffers")
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/smc/smc_core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/smc/smc_core.c
++++ b/net/smc/smc_core.c
+@@ -321,8 +321,8 @@ void smc_conn_free(struct smc_connection
+       } else {
+               smc_cdc_tx_dismiss_slots(conn);
+       }
+-      smc_lgr_unregister_conn(conn);          /* unsets conn->lgr */
+       smc_buf_unuse(conn, lgr);               /* allow buffer reuse */
++      smc_lgr_unregister_conn(conn);          /* unsets conn->lgr */
+       if (!lgr->conns_num)
+               smc_lgr_schedule_free_work(lgr);
index c64647482e40eb4d1efd0e3baeac0b31fe088c57..5f0b6cfc3f83f1cefd14a0f737b99e862334f7b6 100644 (file)
@@ -20,3 +20,9 @@ xfrm-fix-the-if_id-check-in-changelink.patch
 xfrm-enforce-validity-of-offload-input-flags.patch
 netfilter-nf_queue-don-t-assume-sk-is-full-socket.patch
 netfilter-nf_queue-fix-possible-use-after-free.patch
+batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch
+batman-adv-request-iflink-once-in-batadv_get_real_netdevice.patch
+batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch
+net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch
+net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch
+net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch