Commit 8a83a00b0735190384a348156837918271034144

Authored by Arnd Bergmann
Committed by David S. Miller
1 parent 6884b348ed

net: maintain namespace isolation between vlan and real device

In the vlan and macvlan drivers, the start_xmit function forwards
data to the dev_queue_xmit function for another device, which may
potentially belong to a different namespace.

To make sure that classification stays within a single namespace,
this resets the potentially critical fields.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 4 changed files with 42 additions and 6 deletions Side-by-side Diff

drivers/net/macvlan.c
... ... @@ -269,7 +269,7 @@
269 269 }
270 270  
271 271 xmit_world:
272   - skb->dev = vlan->lowerdev;
  272 + skb_set_dev(skb, vlan->lowerdev);
273 273 return dev_queue_xmit(skb);
274 274 }
275 275  
include/linux/netdevice.h
... ... @@ -1004,6 +1004,15 @@
1004 1004 return 0;
1005 1005 }
1006 1006  
  1007 +#ifndef CONFIG_NET_NS
  1008 +static inline void skb_set_dev(struct sk_buff *skb, struct net_device *dev)
  1009 +{
  1010 + skb->dev = dev;
  1011 +}
  1012 +#else /* CONFIG_NET_NS */
  1013 +void skb_set_dev(struct sk_buff *skb, struct net_device *dev);
  1014 +#endif
  1015 +
1007 1016 static inline bool netdev_uses_trailer_tags(struct net_device *dev)
1008 1017 {
1009 1018 #ifdef CONFIG_NET_DSA_TAG_TRAILER
net/8021q/vlan_dev.c
... ... @@ -322,7 +322,7 @@
322 322 }
323 323  
324 324  
325   - skb->dev = vlan_dev_info(dev)->real_dev;
  325 + skb_set_dev(skb, vlan_dev_info(dev)->real_dev);
326 326 len = skb->len;
327 327 ret = dev_queue_xmit(skb);
328 328  
... ... @@ -1448,13 +1448,10 @@
1448 1448 if (skb->len > (dev->mtu + dev->hard_header_len))
1449 1449 return NET_RX_DROP;
1450 1450  
1451   - skb_dst_drop(skb);
  1451 + skb_set_dev(skb, dev);
1452 1452 skb->tstamp.tv64 = 0;
1453 1453 skb->pkt_type = PACKET_HOST;
1454 1454 skb->protocol = eth_type_trans(skb, dev);
1455   - skb->mark = 0;
1456   - secpath_reset(skb);
1457   - nf_reset(skb);
1458 1455 return netif_rx(skb);
1459 1456 }
1460 1457 EXPORT_SYMBOL_GPL(dev_forward_skb);
... ... @@ -1613,6 +1610,36 @@
1613 1610  
1614 1611 return false;
1615 1612 }
  1613 +
  1614 +/**
  1615 + * skb_dev_set -- assign a new device to a buffer
  1616 + * @skb: buffer for the new device
  1617 + * @dev: network device
  1618 + *
  1619 + * If an skb is owned by a device already, we have to reset
  1620 + * all data private to the namespace a device belongs to
  1621 + * before assigning it a new device.
  1622 + */
  1623 +#ifdef CONFIG_NET_NS
  1624 +void skb_set_dev(struct sk_buff *skb, struct net_device *dev)
  1625 +{
  1626 + skb_dst_drop(skb);
  1627 + if (skb->dev && !net_eq(dev_net(skb->dev), dev_net(dev))) {
  1628 + secpath_reset(skb);
  1629 + nf_reset(skb);
  1630 + skb_init_secmark(skb);
  1631 + skb->mark = 0;
  1632 + skb->priority = 0;
  1633 + skb->nf_trace = 0;
  1634 + skb->ipvs_property = 0;
  1635 +#ifdef CONFIG_NET_SCHED
  1636 + skb->tc_index = 0;
  1637 +#endif
  1638 + }
  1639 + skb->dev = dev;
  1640 +}
  1641 +EXPORT_SYMBOL(skb_set_dev);
  1642 +#endif /* CONFIG_NET_NS */
1616 1643  
1617 1644 /*
1618 1645 * Invalidate hardware checksum when packet is to be mangled, and