From 9a75e8256969d5c4973365aedd1c705b620605b3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 12 Mar 2022 14:13:30 +0100 Subject: [PATCH] 4.9-stable patches added patches: batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch --- ...ct-inter-netns-unique-iflink-indices.patch | 72 +++++++++++++++++++ ...flink-once-in-batadv-on-batadv-check.patch | 55 ++++++++++++++ queue-4.9/series | 2 + 3 files changed, 129 insertions(+) create mode 100644 queue-4.9/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch create mode 100644 queue-4.9/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch 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 index 00000000000..7185b5cb38a --- /dev/null +++ b/queue-4.9/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch @@ -0,0 +1,72 @@ +From 6c1f41afc1dbe59d9d3c8bb0d80b749c119aa334 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Sun, 27 Feb 2022 23:23:49 +0100 +Subject: batman-adv: Don't expect inter-netns unique iflink indices + +From: Sven Eckelmann + +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: 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: 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 +Signed-off-by: Sven Eckelmann +Signed-off-by: Simon Wunderlich +[ bp: 4.9 backported: drop modification of non-existing batadv_get_real_netdevice. ] +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..a7477c88e1c --- /dev/null +++ b/queue-4.9/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch @@ -0,0 +1,55 @@ +From 690bb6fb64f5dc7437317153902573ecad67593d Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Mon, 28 Feb 2022 00:01:24 +0100 +Subject: batman-adv: Request iflink once in batadv-on-batadv check + +From: Sven Eckelmann + +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 +Signed-off-by: Simon Wunderlich +[ bp: 4.9 backported: adjust context. ] +Signed-off-by: Sven Eckelmann +Signed-off-by: Greg Kroah-Hartman +--- + 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"); diff --git a/queue-4.9/series b/queue-4.9/series index 19f2fdbdbb7..8684bc08402 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -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 -- 2.47.3