[NET]: Make packet reception network namespace safe
authorEric W. Biederman <ebiederm@xmission.com>
Mon, 17 Sep 2007 18:53:39 +0000 (11:53 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 10 Oct 2007 23:49:08 +0000 (16:49 -0700)
This patch modifies every packet receive function
registered with dev_add_pack() to drop packets if they
are not from the initial network namespace.

This should ensure that the various network stacks do
not receive packets in a anything but the initial network
namespace until the code has been converted and is ready
for them.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
26 files changed:
drivers/block/aoe/aoenet.c
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_main.c
drivers/net/hamradio/bpqether.c
drivers/net/pppoe.c
drivers/net/wan/hdlc.c
drivers/net/wan/lapbether.c
drivers/net/wan/syncppp.c
net/8021q/vlan_dev.c
net/appletalk/aarp.c
net/appletalk/ddp.c
net/ax25/ax25_in.c
net/bridge/br_stp_bpdu.c
net/decnet/dn_route.c
net/econet/af_econet.c
net/ipv4/arp.c
net/ipv4/ip_input.c
net/ipv4/ipconfig.c
net/ipv6/ip6_input.c
net/ipx/af_ipx.c
net/irda/irlap_frame.c
net/llc/llc_input.c
net/packet/af_packet.c
net/tipc/eth_media.c
net/x25/x25_dev.c

index f9ddfda4d9cb5945e3800e4a6865691e6069765f..4dc0fb7da94b50dacbdb0084dc7f7f037f0db435 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/blkdev.h>
 #include <linux/netdevice.h>
 #include <linux/moduleparam.h>
+#include <net/net_namespace.h>
 #include <asm/unaligned.h>
 #include "aoe.h"
 
@@ -114,6 +115,9 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
        struct aoe_hdr *h;
        u32 n;
 
+       if (ifp->nd_net != &init_net)
+               goto exit;
+
        skb = skb_share_check(skb, GFP_ATOMIC);
        if (skb == NULL)
                return 0;
index f829e4ad8b4970aacd1cc893e0c65a7855f751bd..94bd739414517a0d35f98ee31c80c9175043ee9d 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/ethtool.h>
 #include <linux/if_bonding.h>
 #include <linux/pkt_sched.h>
+#include <net/net_namespace.h>
 #include "bonding.h"
 #include "bond_3ad.h"
 
@@ -2448,6 +2449,9 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac
        struct slave *slave = NULL;
        int ret = NET_RX_DROP;
 
+       if (dev->nd_net != &init_net)
+               goto out;
+
        if (!(dev->flags & IFF_MASTER))
                goto out;
 
index 92c3b6f6a8e7977779ca5c013745bd37ea95da32..419a9f8fdd53b66d3d1170f37937a6a89723c7e7 100644 (file)
@@ -345,6 +345,9 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct
        struct arp_pkt *arp = (struct arp_pkt *)skb->data;
        int res = NET_RX_DROP;
 
+       if (bond_dev->nd_net != &init_net)
+               goto out;
+
        if (!(bond_dev->flags & IFF_MASTER))
                goto out;
 
index 5de648f90a458106e406bf6881ab3b03344263e2..e4e5fdc0430b78514794469ff7c63a46988f33cb 100644 (file)
@@ -2458,6 +2458,9 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
        unsigned char *arp_ptr;
        u32 sip, tip;
 
+       if (dev->nd_net != &init_net)
+               goto out;
+
        if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
                goto out;
 
index 1699d42d13ca417d504058e581054d2c4fd7fde0..85fb8e7efacf0a2bdbf127a10510f342c01f788c 100644 (file)
@@ -173,6 +173,9 @@ static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty
        struct ethhdr *eth;
        struct bpqdev *bpq;
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
                return NET_RX_DROP;
 
index 53fcee26d6ae6435014c094d0fd6337d19b265ad..60c0e4e17875685dcca9657994023f9b08de99aa 100644 (file)
@@ -389,6 +389,9 @@ static int pppoe_rcv(struct sk_buff *skb,
        if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
                goto out;
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
                goto drop;
 
@@ -418,6 +421,9 @@ static int pppoe_disc_rcv(struct sk_buff *skb,
        struct pppoe_hdr *ph;
        struct pppox_sock *po;
 
+       if (dev->nd_net != &init_net)
+               goto abort;
+
        if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
                goto abort;
 
index 65ad2e24caf071a5aa16a0a710a7b07c05c75aa3..3b57350eacca7a6e9a671e1fd9e469a83e7f5c55 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/notifier.h>
 #include <linux/hdlc.h>
+#include <net/net_namespace.h>
 
 
 static const char* version = "HDLC support module revision 1.21";
@@ -66,6 +67,12 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
                    struct packet_type *p, struct net_device *orig_dev)
 {
        struct hdlc_device_desc *desc = dev_to_desc(dev);
+
+       if (dev->nd_net != &init_net) {
+               kfree_skb(skb);
+               return 0;
+       }
+
        if (desc->netif_rx)
                return desc->netif_rx(skb);
 
index 6c302e9dbca2e2ee2aeabf570e0c37cca193c88b..ca8b3c3cb931850c8df19de6de82054e0cf2abde 100644 (file)
@@ -91,6 +91,9 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
        int len, err;
        struct lapbethdev *lapbeth;
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
                return NET_RX_DROP;
 
index 67fc67cfd452562768adb8b09bfb369ca0f1e360..5c71af6ea3a50ad99d91845fbce3247cbebdf7d8 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/spinlock.h>
 #include <linux/rcupdate.h>
 
+#include <net/net_namespace.h>
 #include <net/syncppp.h>
 
 #include <asm/byteorder.h>
@@ -1445,6 +1446,11 @@ static void sppp_print_bytes (u_char *p, u16 len)
 
 static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p, struct net_device *orig_dev)
 {
+       if (dev->nd_net != &init_net) {
+               kfree_skb(skb);
+               return 0;
+       }
+
        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
                return NET_RX_DROP;
        sppp_input(dev,skb);
index 328759c32d616195ff634ad12369667d16e4f80e..6644e8f5f19992a62010bd3f9810fa39bdf8be7c 100644 (file)
@@ -122,6 +122,11 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
        unsigned short vlan_TCI;
        __be16 proto;
 
+       if (dev->nd_net != &init_net) {
+               kfree_skb(skb);
+               return -1;
+       }
+
        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
                return -1;
 
index 80b54148460f5614a8290f8edf655eaf5407a70d..9267f4818795d3d469f68b667c8ab0fe9792d592 100644 (file)
@@ -713,6 +713,9 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,
        struct atalk_addr sa, *ma, da;
        struct atalk_iface *ifa;
 
+       if (dev->nd_net != &init_net)
+               goto out0;
+
        /* We only do Ethernet SNAP AARP. */
        if (dev->type != ARPHRD_ETHER)
                goto out0;
index fd1d52f0970767725a3920281631333444be274c..c1f1367cad483c5eba04f72a4d14938b9e9cdf7c 100644 (file)
@@ -1403,6 +1403,9 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
        int origlen;
        __u16 len_hops;
 
+       if (dev->nd_net != &init_net)
+               goto freeit;
+
        /* Don't mangle buffer if shared */
        if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
                goto out;
@@ -1488,6 +1491,9 @@ freeit:
 static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
                     struct packet_type *pt, struct net_device *orig_dev)
 {
+       if (dev->nd_net != &init_net)
+               goto freeit;
+
        /* Expand any short form frames */
        if (skb_mac_header(skb)[2] == 1) {
                struct ddpehdr *ddp;
index 0ddaff0df217d37e58c0e920f0c401e4dde330cb..3b7d1720c2eee2c3d652526f74f92094bb4634b4 100644 (file)
@@ -451,6 +451,11 @@ int ax25_kiss_rcv(struct sk_buff *skb, struct net_device *dev,
        skb->sk = NULL;         /* Initially we don't know who it's for */
        skb->destructor = NULL; /* Who initializes this, dammit?! */
 
+       if (dev->nd_net != &init_net) {
+               kfree_skb(skb);
+               return 0;
+       }
+
        if ((*skb->data & 0x0F) != 0) {
                kfree_skb(skb); /* Not a KISS data frame */
                return 0;
index 14f0c888eecc4f87cb46fe2dd4a379bb501fbc25..0edbd2a1c3f3cafe6d2046360f92b5a9084235f3 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/netfilter_bridge.h>
 #include <linux/etherdevice.h>
 #include <linux/llc.h>
+#include <net/net_namespace.h>
 #include <net/llc.h>
 #include <net/llc_pdu.h>
 #include <asm/unaligned.h>
@@ -141,6 +142,9 @@ int br_stp_rcv(struct sk_buff *skb, struct net_device *dev,
        struct net_bridge *br;
        const unsigned char *buf;
 
+       if (dev->nd_net != &init_net)
+               goto err;
+
        if (!p)
                goto err;
 
index 4cfea9563d2abe67cae6ddedab03c90c79b09083..580e786d0c3862ccc6fea2e0d25c47f5646aa7f4 100644 (file)
@@ -584,6 +584,9 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
        struct dn_dev *dn = (struct dn_dev *)dev->dn_ptr;
        unsigned char padlen = 0;
 
+       if (dev->nd_net != &init_net)
+               goto dump_it;
+
        if (dn == NULL)
                goto dump_it;
 
index a2429dbcb86ee3639e4536754176798f02b2a7ff..7de3006af206c7feb0dc42de79e2690ee8d9331b 100644 (file)
@@ -1065,6 +1065,9 @@ static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
        struct sock *sk;
        struct ec_device *edev = dev->ec_ptr;
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        if (skb->pkt_type == PACKET_OTHERHOST)
                goto drop;
 
index 78dd3443016c1e519ad8b9a141bc300ec559dd23..bde129708e2282e310d10e56157a77e389a4a5ea 100644 (file)
@@ -932,6 +932,9 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
 {
        struct arphdr *arp;
 
+       if (dev->nd_net != &init_net)
+               goto freeskb;
+
        /* ARP header, plus 2 device addresses, plus 2 IP addresses.  */
        if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
                                 (2 * dev->addr_len) +
index 97069399d8645ffe3e4af364ba353db7a1011687..41d8964591e785420f6800ab3329d87cc2884704 100644 (file)
@@ -382,6 +382,9 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
        struct iphdr *iph;
        u32 len;
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        /* When the interface is in promisc. mode, drop all the crap
         * that it receives, do not try to analyse it.
         */
index 5ae4849878a32678aa6e622eaba45dd6b1ef3f73..08ff623371f08252d24d261a55275794267fa948 100644 (file)
@@ -426,6 +426,9 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
        unsigned char *sha, *tha;               /* s for "source", t for "target" */
        struct ic_device *d;
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
                return NET_RX_DROP;
 
@@ -835,6 +838,9 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
        struct ic_device *d;
        int len, ext_len;
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        /* Perform verifications before taking the lock.  */
        if (skb->pkt_type == PACKET_OTHERHOST)
                goto drop;
index 30a5cb1b203e1e644c0e3182692b91549c9c9725..7d18cac3f1109d1df736106d6a562f8830f8fadb 100644 (file)
@@ -61,6 +61,11 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
        u32             pkt_len;
        struct inet6_dev *idev;
 
+       if (dev->nd_net != &init_net) {
+               kfree_skb(skb);
+               return 0;
+       }
+
        if (skb->pkt_type == PACKET_OTHERHOST) {
                kfree_skb(skb);
                return 0;
index ee28babad22782c782cbf104ae314c3b47b5dd66..f7b4d383c60958a8daebc38c1188cfacc69254ef 100644 (file)
@@ -1647,6 +1647,9 @@ static int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty
        u16 ipx_pktsize;
        int rc = 0;
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        /* Not ours */
        if (skb->pkt_type == PACKET_OTHERHOST)
                goto drop;
index 25a3444a9234f1faba7ba2e2e88b18e452d1f44f..77ac27e811615a2e801f22c188d59762bf0ae431 100644 (file)
@@ -1326,6 +1326,9 @@ int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
        int command;
        __u8 control;
 
+       if (dev->nd_net != &init_net)
+               goto out;
+
        /* FIXME: should we get our own field? */
        self = (struct irlap_cb *) dev->atalk_ptr;
 
index 099ed8fec1454b3f38822f0e3d8e0870108e52d7..c40c9b2a345aca6058d222ad662f4a830c943d7e 100644 (file)
@@ -12,6 +12,7 @@
  * See the GNU General Public License for more details.
  */
 #include <linux/netdevice.h>
+#include <net/net_namespace.h>
 #include <net/llc.h>
 #include <net/llc_pdu.h>
 #include <net/llc_sap.h>
@@ -145,6 +146,9 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
        int (*rcv)(struct sk_buff *, struct net_device *,
                   struct packet_type *, struct net_device *);
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        /*
         * When the interface is in promisc. mode, drop all the crap that it
         * receives, do not try to analyse it.
index 766b5faaed21aa88de5d0a675a5186505276e7c2..cae1ee4f2ad68a7f1d13552dd97c5787fc71479c 100644 (file)
@@ -252,6 +252,9 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct
        struct sock *sk;
        struct sockaddr_pkt *spkt;
 
+       if (dev->nd_net != &init_net)
+               goto out;
+
        /*
         *      When we registered the protocol we saved the socket in the data
         *      field for just this event.
@@ -452,6 +455,9 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
        int skb_len = skb->len;
        unsigned int snaplen, res;
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        if (skb->pkt_type == PACKET_LOOPBACK)
                goto drop;
 
@@ -568,6 +574,9 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
        struct sk_buff *copy_skb = NULL;
        struct timeval tv;
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        if (skb->pkt_type == PACKET_LOOPBACK)
                goto drop;
 
index 711ca4b1f051720ca546d6e722e1ab387a20ed21..d2ed23704189d3c59238c20fc4c25510512cb9a6 100644 (file)
@@ -38,6 +38,7 @@
 #include <net/tipc/tipc_bearer.h>
 #include <net/tipc/tipc_msg.h>
 #include <linux/netdevice.h>
+#include <net/net_namespace.h>
 
 #define MAX_ETH_BEARERS                2
 #define ETH_LINK_PRIORITY      TIPC_DEF_LINK_PRI
@@ -100,6 +101,11 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev,
        struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv;
        u32 size;
 
+       if (dev->nd_net != &init_net) {
+               kfree_skb(buf);
+               return 0;
+       }
+
        if (likely(eb_ptr->bearer)) {
                if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
                        size = msg_size((struct tipc_msg *)buf->data);
index 848a6b6f90a658d98167916e3d118a1907df28ba..f0679d283110885e4e7f29f7358e07df3c753e49 100644 (file)
@@ -95,6 +95,9 @@ int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev,
        struct sk_buff *nskb;
        struct x25_neigh *nb;
 
+       if (dev->nd_net != &init_net)
+               goto drop;
+
        nskb = skb_copy(skb, GFP_ATOMIC);
        if (!nskb)
                goto drop;