Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ce6cebc authored by Daniel Lezcano's avatar Daniel Lezcano Committed by David S. Miller
Browse files

net-2.6 : V2 - fix dev_get_valid_name

the commit:

commit d9031024
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: default avatarDaniel Lezcano <daniel.lezcano@free.fr>
Reviewed-by: default avatarOctavian Purdila <opurdila@ixiacom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a4ed89cb
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -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;
	}