]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 12 Mar 2022 13:13:30 +0000 (14:13 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 12 Mar 2022 13:13:30 +0000 (14:13 +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

queue-4.9/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch [new file with mode: 0644]
queue-4.9/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch b/queue-4.9/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch
new file mode 100644 (file)
index 0000000..7185b5c
--- /dev/null
@@ -0,0 +1,72 @@
+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>
+[ bp: 4.9 backported: drop modification of non-existing batadv_get_real_netdevice. ]
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/hard-interface.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -163,13 +163,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.. */
diff --git a/queue-4.9/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch b/queue-4.9/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch
new file mode 100644 (file)
index 0000000..a7477c8
--- /dev/null
@@ -0,0 +1,55 @@
+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>
+[ bp: 4.9 backported: adjust context. ]
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+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
+@@ -155,22 +155,23 @@ static bool batadv_is_on_batman_iface(co
+       struct net *net = dev_net(net_dev);
+       struct net_device *parent_dev;
+       const 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");
index 19f2fdbdbb7e9b1383ed0050b77901e3a340ee62..8684bc08402ccf3c8eee424ff4bde795cdee1a0b 100644 (file)
@@ -14,3 +14,5 @@ selftests-memfd-clean-up-mapping-in-mfd_fail_write.patch
 arm-spectre-bhb-provide-empty-stub-for-non-config.patch
 staging-gdm724x-fix-use-after-free-in-gdm_lte_rx.patch
 kvm-arm64-reset-pmc_el0-to-avoid-a-panic-on-systems-with-no-pmu.patch
+batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch
+batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch