Skip to content

Commit 7663d52

Browse files
kuba-mooPaolo Abeni
authored andcommitted
net: check for altname conflicts when changing netdev's netns
It's currently possible to create an altname conflicting with an altname or real name of another device by creating it in another netns and moving it over: [ ~]$ ip link add dev eth0 type dummy [ ~]$ ip netns add test [ ~]$ ip -netns test link add dev ethX netns test type dummy [ ~]$ ip -netns test link property add dev ethX altname eth0 [ ~]$ ip -netns test link set dev ethX netns 1 [ ~]$ ip link ... 3: eth0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 02:40:88:62:ec:b8 brd ff:ff:ff:ff:ff:ff ... 5: ethX: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 26:b7:28:78:38:0f brd ff:ff:ff:ff:ff:ff altname eth0 Create a macro for walking the altnames, this hopefully makes it clearer that the list we walk contains only altnames. Which is otherwise not entirely intuitive. Fixes: 36fbf1e ("net: rtnetlink: add linkprop commands to add and delete alternative ifnames") Reviewed-by: Jiri Pirko <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 311cca4 commit 7663d52

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

net/core/dev.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,8 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf)
10861086

10871087
for_each_netdev(net, d) {
10881088
struct netdev_name_node *name_node;
1089-
list_for_each_entry(name_node, &d->name_node->list, list) {
1089+
1090+
netdev_for_each_altname(d, name_node) {
10901091
if (!sscanf(name_node->name, name, &i))
10911092
continue;
10921093
if (i < 0 || i >= max_netdevices)
@@ -11051,6 +11052,7 @@ EXPORT_SYMBOL(unregister_netdev);
1105111052
int __dev_change_net_namespace(struct net_device *dev, struct net *net,
1105211053
const char *pat, int new_ifindex)
1105311054
{
11055+
struct netdev_name_node *name_node;
1105411056
struct net *net_old = dev_net(dev);
1105511057
char new_name[IFNAMSIZ] = {};
1105611058
int err, new_nsid;
@@ -11083,6 +11085,11 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
1108311085
if (err < 0)
1108411086
goto out;
1108511087
}
11088+
/* Check that none of the altnames conflicts. */
11089+
err = -EEXIST;
11090+
netdev_for_each_altname(dev, name_node)
11091+
if (netdev_name_in_use(net, name_node->name))
11092+
goto out;
1108611093

1108711094
/* Check that new_ifindex isn't used yet. */
1108811095
if (new_ifindex) {

net/core/dev.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ struct netdev_name_node {
6262
int netdev_get_name(struct net *net, char *name, int ifindex);
6363
int dev_change_name(struct net_device *dev, const char *newname);
6464

65+
#define netdev_for_each_altname(dev, namenode) \
66+
list_for_each_entry((namenode), &(dev)->name_node->list, list)
67+
6568
int netdev_name_node_alt_create(struct net_device *dev, const char *name);
6669
int netdev_name_node_alt_destroy(struct net_device *dev, const char *name);
6770

0 commit comments

Comments
 (0)