Subject: [PATCH] nethost ipv4: Don't allow global ipv4 addresses that another nethost is already using. From: Eric W. Biederman Date: 1134399578 -0700 --- net/ipv4/devinet.c | 38 +++++++++++++++++++++++++++++++++++++- 1 files changed, 37 insertions(+), 1 deletions(-) 2c69965eabaee127f4bfafa745b0bb7cb12c21e6 diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 139b23c..e3345bc 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -183,8 +183,9 @@ static void in_dev_rcu_put(struct rcu_he static void inethost_destroy(struct nethost *host) { - /* FIXME is the locking correct in this function? */ struct net_device *dev; + ASSERT_RTNL(); + if (!host) return; read_lock(&dev_base_lock); @@ -330,6 +331,34 @@ static void inet_del_ifa(struct in_devic } } +static int inet_chk_same_host_addr(u32 addr, struct in_device *adev, + struct nethost *host) +{ + struct net_device *dev; + struct in_ifaddr *ifa = NULL; + + read_lock(&dev_base_lock); + rcu_read_lock(); + for (dev = dev_base; dev; dev = dev->next) { + struct in_device *idev; + if ((idev = __in_dev_get_rcu(dev)) == NULL) + continue; + for(ifa = idev->ifa_list; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_local == addr) { + if (adev == NULL || ifa->ifa_dev == adev) + goto out; + if (host && (ifa->ifa_host != host) && + (ifa->ifa_scope < RT_SCOPE_LINK)) + goto out; + } + } + } + out: + rcu_read_unlock(); + read_unlock(&dev_base_lock); + return ifa != NULL; +} + static int inet_insert_ifa(struct in_ifaddr *ifa) { struct in_device *in_dev = ifa->ifa_dev; @@ -342,6 +371,13 @@ static int inet_insert_ifa(struct in_ifa return 0; } + /* Deny adding duplicate address on a interface */ + /* Deny adding global addresses already used by another host */ + if (inet_chk_same_host_addr(ifa->ifa_local, ifa->ifa_dev, ifa->ifa_host)) { + inet_free_ifa(ifa); + return -EEXIST; + } + /* Deny adding addresses owned by other hosts to the loopback device */ if ((ifa->ifa_dev->dev->flags & IFF_LOOPBACK) && (ifa->ifa_dev->dev != &ifa->ifa_host->loopback_dev)) { -- 1.0.GIT