Skip to content

Commit

Permalink
[NET]: Make device event notification network namespace safe
Browse files Browse the repository at this point in the history
Every user of the network device notifiers is either a protocol
stack or a pseudo device.  If a protocol stack that does not have
support for multiple network namespaces receives an event for a
device that is not in the initial network namespace it quite possibly
can get confused and do the wrong thing.

To avoid problems until all of the protocol stacks are converted
this patch modifies all netdev event handlers to ignore events on
devices that are not in the initial network namespace.

As the rest of the code is made network namespace aware these
checks can be removed.

Signed-off-by: Eric W. Biederman <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
ebiederm authored and David S. Miller committed Oct 10, 2007
1 parent e730c15 commit e9dc865
Show file tree
Hide file tree
Showing 38 changed files with 126 additions and 1 deletion.
3 changes: 3 additions & 0 deletions arch/ia64/hp/sim/simeth.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
return NOTIFY_DONE;
}

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if ( event != NETDEV_UP && event != NETDEV_DOWN ) return NOTIFY_DONE;

/*
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/bonding/bond_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3299,6 +3299,9 @@ static int bond_netdev_event(struct notifier_block *this, unsigned long event, v
{
struct net_device *event_dev = (struct net_device *)ptr;

if (event_dev->nd_net != &init_net)
return NOTIFY_DONE;

dprintk("event_dev: %s, event: %lx\n",
(event_dev ? event_dev->name : "None"),
event);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/hamradio/bpqether.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,9 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi
{
struct net_device *dev = (struct net_device *)ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (!dev_is_ethdev(dev))
return NOTIFY_DONE;

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/pppoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ static int pppoe_device_event(struct notifier_block *this,
{
struct net_device *dev = (struct net_device *) ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

/* Only look at sockets that are using this specific device. */
switch (event) {
case NETDEV_CHANGEMTU:
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wan/dlci.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,9 @@ static int dlci_dev_event(struct notifier_block *unused,
{
struct net_device *dev = (struct net_device *) ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (event == NETDEV_UNREGISTER) {
struct dlci_local *dlp;

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wan/hdlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ static int hdlc_device_event(struct notifier_block *this, unsigned long event,
unsigned long flags;
int on;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (dev->get_stats != hdlc_get_stats)
return NOTIFY_DONE; /* not an HDLC device */

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wan/lapbether.c
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,9 @@ static int lapbeth_device_event(struct notifier_block *this,
struct lapbethdev *lapbeth;
struct net_device *dev = ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (!dev_is_ethdev(dev))
return NOTIFY_DONE;

Expand Down
4 changes: 4 additions & 0 deletions net/8021q/vlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <net/arp.h>
#include <linux/rtnetlink.h>
#include <linux/notifier.h>
#include <net/net_namespace.h>

#include <linux/if_vlan.h>
#include "vlan.h"
Expand Down Expand Up @@ -603,6 +604,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
int i, flgs;
struct net_device *vlandev;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (!grp)
goto out;

Expand Down
3 changes: 3 additions & 0 deletions net/appletalk/aarp.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ static int aarp_device_event(struct notifier_block *this, unsigned long event,
struct net_device *dev = ptr;
int ct;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (event == NETDEV_DOWN) {
write_lock_bh(&aarp_lock);

Expand Down
3 changes: 3 additions & 0 deletions net/appletalk/ddp.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,9 @@ static int ddp_device_event(struct notifier_block *this, unsigned long event,
{
struct net_device *dev = ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (event == NETDEV_DOWN)
/* Discard any use of this */
atalk_dev_down(dev);
Expand Down
3 changes: 3 additions & 0 deletions net/atm/clip.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,9 @@ static int clip_device_event(struct notifier_block *this, unsigned long event,
{
struct net_device *dev = arg;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (event == NETDEV_UNREGISTER) {
neigh_ifdown(&clip_tbl, dev);
return NOTIFY_DONE;
Expand Down
4 changes: 4 additions & 0 deletions net/atm/mpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -956,6 +956,10 @@ static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned lo
struct lec_priv *priv;

dev = (struct net_device *)dev_ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (dev->name == NULL || strncmp(dev->name, "lec", 3))
return NOTIFY_DONE; /* we are only interested in lec:s */

Expand Down
3 changes: 3 additions & 0 deletions net/ax25/af_ax25.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ static int ax25_device_event(struct notifier_block *this, unsigned long event,
{
struct net_device *dev = (struct net_device *)ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

/* Reject non AX.25 devices */
if (dev->type != ARPHRD_AX25)
return NOTIFY_DONE;
Expand Down
4 changes: 4 additions & 0 deletions net/bridge/br_notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include <linux/kernel.h>
#include <linux/rtnetlink.h>
#include <net/net_namespace.h>

#include "br_private.h"

Expand All @@ -36,6 +37,9 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
struct net_bridge_port *p = dev->br_port;
struct net_bridge *br;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

/* not a port of a bridge */
if (p == NULL)
return NOTIFY_DONE;
Expand Down
4 changes: 4 additions & 0 deletions net/core/dst.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/skbuff.h>
#include <linux/string.h>
#include <linux/types.h>
#include <net/net_namespace.h>

#include <net/dst.h>

Expand Down Expand Up @@ -252,6 +253,9 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, void
struct net_device *dev = ptr;
struct dst_entry *dst;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

switch (event) {
case NETDEV_UNREGISTER:
case NETDEV_DOWN:
Expand Down
4 changes: 4 additions & 0 deletions net/core/fib_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <net/net_namespace.h>
#include <net/fib_rules.h>

static LIST_HEAD(rules_ops);
Expand Down Expand Up @@ -596,6 +597,9 @@ static int fib_rules_event(struct notifier_block *this, unsigned long event,
struct net_device *dev = ptr;
struct fib_rules_ops *ops;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

ASSERT_RTNL();
rcu_read_lock();

Expand Down
3 changes: 3 additions & 0 deletions net/core/pktgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1975,6 +1975,9 @@ static int pktgen_device_event(struct notifier_block *unused,
{
struct net_device *dev = ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

/* It is OK that we do not hold the group lock right now,
* as we run under the RTNL lock.
*/
Expand Down
4 changes: 4 additions & 0 deletions net/core/rtnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1286,6 +1286,10 @@ static void rtnetlink_rcv(struct sock *sk, int len)
static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

switch (event) {
case NETDEV_UNREGISTER:
rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
Expand Down
3 changes: 3 additions & 0 deletions net/decnet/af_decnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -2089,6 +2089,9 @@ static int dn_device_event(struct notifier_block *this, unsigned long event,
{
struct net_device *dev = (struct net_device *)ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

switch(event) {
case NETDEV_UP:
dn_dev_up(dev);
Expand Down
3 changes: 3 additions & 0 deletions net/econet/af_econet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,9 @@ static int econet_notifier(struct notifier_block *this, unsigned long msg, void
struct net_device *dev = (struct net_device *)data;
struct ec_device *edev;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

switch (msg) {
case NETDEV_UNREGISTER:
/* A device has gone down - kill any data we hold for it. */
Expand Down
3 changes: 3 additions & 0 deletions net/ipv4/arp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,9 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event, vo
{
struct net_device *dev = ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

switch (event) {
case NETDEV_CHANGEADDR:
neigh_changeaddr(&arp_tbl, dev);
Expand Down
3 changes: 3 additions & 0 deletions net/ipv4/devinet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,9 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
struct net_device *dev = ptr;
struct in_device *in_dev = __in_dev_get_rtnl(dev);

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

ASSERT_RTNL();

if (!in_dev) {
Expand Down
3 changes: 3 additions & 0 deletions net/ipv4/fib_frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,9 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
struct net_device *dev = ptr;
struct in_device *in_dev = __in_dev_get_rtnl(dev);

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (event == NETDEV_UNREGISTER) {
fib_disable_ip(dev, 2);
return NOTIFY_DONE;
Expand Down
7 changes: 6 additions & 1 deletion net/ipv4/ipmr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1083,13 +1083,18 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)

static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = ptr;
struct vif_device *v;
int ct;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (event != NETDEV_UNREGISTER)
return NOTIFY_DONE;
v=&vif_table[0];
for (ct=0;ct<maxvif;ct++,v++) {
if (v->dev==ptr)
if (v->dev==dev)
vif_delete(ct);
}
return NOTIFY_DONE;
Expand Down
3 changes: 3 additions & 0 deletions net/ipv4/netfilter/ip_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,9 @@ ipq_rcv_dev_event(struct notifier_block *this,
{
struct net_device *dev = ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

/* Drop any packets associated with the downed device */
if (event == NETDEV_DOWN)
ipq_dev_drop(dev->ifindex);
Expand Down
3 changes: 3 additions & 0 deletions net/ipv4/netfilter/ipt_MASQUERADE.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ static int masq_device_event(struct notifier_block *this,
{
const struct net_device *dev = ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (event == NETDEV_DOWN) {
/* Device was downed. Search entire table for
conntracks which were associated with that device,
Expand Down
3 changes: 3 additions & 0 deletions net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2259,6 +2259,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
int run_pending = 0;
int err;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

switch(event) {
case NETDEV_REGISTER:
if (!idev && dev->mtu >= IPV6_MIN_MTU) {
Expand Down
3 changes: 3 additions & 0 deletions net/ipv6/ndisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,9 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event,
{
struct net_device *dev = ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

switch (event) {
case NETDEV_CHANGEADDR:
neigh_changeaddr(&nd_tbl, dev);
Expand Down
3 changes: 3 additions & 0 deletions net/ipv6/netfilter/ip6_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,9 @@ ipq_rcv_dev_event(struct notifier_block *this,
{
struct net_device *dev = ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

/* Drop any packets associated with the downed device */
if (event == NETDEV_DOWN)
ipq_dev_drop(dev->ifindex);
Expand Down
3 changes: 3 additions & 0 deletions net/ipx/af_ipx.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ static int ipxitf_device_event(struct notifier_block *notifier,
struct net_device *dev = ptr;
struct ipx_interface *i, *tmp;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (event != NETDEV_DOWN && event != NETDEV_UP)
goto out;

Expand Down
3 changes: 3 additions & 0 deletions net/netfilter/nfnetlink_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,9 @@ nfqnl_rcv_dev_event(struct notifier_block *this,
{
struct net_device *dev = ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

/* Drop any packets associated with the downed device */
if (event == NETDEV_DOWN)
nfqnl_dev_drop(dev->ifindex);
Expand Down
3 changes: 3 additions & 0 deletions net/netrom/af_netrom.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ static int nr_device_event(struct notifier_block *this, unsigned long event, voi
{
struct net_device *dev = (struct net_device *)ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (event != NETDEV_DOWN)
return NOTIFY_DONE;

Expand Down
3 changes: 3 additions & 0 deletions net/packet/af_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,9 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void
struct hlist_node *node;
struct net_device *dev = data;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

read_lock(&packet_sklist_lock);
sk_for_each(sk, node, &packet_sklist) {
struct packet_sock *po = pkt_sk(sk);
Expand Down
3 changes: 3 additions & 0 deletions net/rose/af_rose.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ static int rose_device_event(struct notifier_block *this, unsigned long event,
{
struct net_device *dev = (struct net_device *)ptr;

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

if (event != NETDEV_DOWN)
return NOTIFY_DONE;

Expand Down
3 changes: 3 additions & 0 deletions net/tipc/eth_media.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ static int recv_notification(struct notifier_block *nb, unsigned long evt,
struct eth_bearer *eb_ptr = &eth_bearers[0];
struct eth_bearer *stop = &eth_bearers[MAX_ETH_BEARERS];

if (dev->nd_net != &init_net)
return NOTIFY_DONE;

while ((eb_ptr->dev != dev)) {
if (++eb_ptr == stop)
return NOTIFY_DONE; /* couldn't find device */
Expand Down
Loading

0 comments on commit e9dc865

Please sign in to comment.