mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-01 16:14:13 +08:00
net-2.6 : V2 - fix dev_get_valid_name
the commit:
commit d90310243f
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>
This commit is contained in:
parent
a4ed89cb92
commit
8ce6cebc2f
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user