Skip to content

Commit

Permalink
net-2.6 : V2 - fix dev_get_valid_name
Browse files Browse the repository at this point in the history
the commit:

commit d903102
Author: Octavian Purdila <opurdila@ixiacom.com>
Date:   Wed Nov 18 02:36:59 2009 +0000

    net: device name allocation cleanups

introduced a bug when there is a hash collision making impossible
to rename a device with eth%d. This bug is very hard to reproduce
and appears rarely.

The problem is coming from we don't pass a temporary buffer to
__dev_alloc_name but 'dev->name' which is modified by the function.

A detailed explanation is here:

http://marc.info/?l=linux-netdev&m=127417784011987&w=2

Changelog:
 V2 : replaced strings comparison by pointers comparison

Signed-off-by: Daniel Lezcano <daniel.lezcano@free.fr>
Reviewed-by: Octavian Purdila <opurdila@ixiacom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Daniel Lezcano authored and David S. Miller committed May 24, 2010
1 parent a4ed89c commit 8ce6ceb
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -954,18 +954,22 @@ int dev_alloc_name(struct net_device *dev, const char *name)
}
EXPORT_SYMBOL(dev_alloc_name);

static int dev_get_valid_name(struct net *net, const char *name, char *buf,
bool fmt)
static int dev_get_valid_name(struct net_device *dev, const char *name, bool fmt)
{
struct net *net;

BUG_ON(!dev_net(dev));
net = dev_net(dev);

if (!dev_valid_name(name))
return -EINVAL;

if (fmt && strchr(name, '%'))
return __dev_alloc_name(net, name, buf);
return dev_alloc_name(dev, name);
else if (__dev_get_by_name(net, name))
return -EEXIST;
else if (buf != name)
strlcpy(buf, name, IFNAMSIZ);
else if (dev->name != name)
strlcpy(dev->name, name, IFNAMSIZ);

return 0;
}
Expand Down Expand Up @@ -997,7 +1001,7 @@ int dev_change_name(struct net_device *dev, const char *newname)

memcpy(oldname, dev->name, IFNAMSIZ);

err = dev_get_valid_name(net, newname, dev->name, 1);
err = dev_get_valid_name(dev, newname, 1);
if (err < 0)
return err;

Expand Down Expand Up @@ -4965,7 +4969,7 @@ int register_netdevice(struct net_device *dev)
}
}

ret = dev_get_valid_name(net, dev->name, dev->name, 0);
ret = dev_get_valid_name(dev, dev->name, 0);
if (ret)
goto err_uninit;

Expand Down Expand Up @@ -5574,7 +5578,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
/* We get here if we can't use the current device name */
if (!pat)
goto out;
if (dev_get_valid_name(net, pat, dev->name, 1))
if (dev_get_valid_name(dev, pat, 1))
goto out;
}

Expand Down

0 comments on commit 8ce6ceb

Please sign in to comment.