Skip to content

Commit

Permalink
batman-adv: Don't expect inter-netns unique iflink indices
Browse files Browse the repository at this point in the history
commit 6c1f41a 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: b7eddd0 ("batman-adv: prevent using any virtual device created on batman-adv as hard-interface")
Fixes: 5ed4a46 ("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>
  • Loading branch information
ecsv authored and gregkh committed Mar 8, 2022
1 parent 9c336fe commit e1d826e
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions net/batman-adv/hard-interface.c
Expand Up @@ -157,13 +157,15 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
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.. */
Expand Down Expand Up @@ -223,8 +225,7 @@ static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)
return NULL;

iflink = dev_get_iflink(netdev);

if (netdev->ifindex == iflink) {
if (iflink == 0) {
dev_hold(netdev);
return netdev;
}
Expand All @@ -235,6 +236,14 @@ static struct net_device *batadv_get_real_netdevice(struct net_device *netdev)

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:
Expand Down

0 comments on commit e1d826e

Please sign in to comment.