|
Jiri Bohac |
340041 |
From: Jiri Bohac <jbohac@suse.cz>
|
|
Jiri Bohac |
340041 |
Subject: net: make __dev_alloc_name consider all name nodes when looking for
|
|
Jiri Bohac |
340041 |
References: bsc#1180103
|
|
Jiri Bohac |
340041 |
Acked-by: Jiri Bohac <jbohac@suse.cz>
|
|
Jeff Mahoney |
bb0636 |
Git-commit: 6c015a2256801597fadcbc11d287774c9c512fa5
|
|
Jeff Mahoney |
bb0636 |
Patch-mainline: v5.12-rc5
|
|
Jiri Bohac |
340041 |
|
|
Jiri Bohac |
340041 |
__dev_alloc_name(), when supplied with a name containing '%d', will search for the first
|
|
Jiri Bohac |
340041 |
available device number to filled in the name.
|
|
Jiri Bohac |
340041 |
|
|
Jiri Bohac |
340041 |
Since commit ff92741270bf8b6e78aa885f166b68c7a67ab13a ("net: introduce
|
|
Jiri Bohac |
340041 |
name_node struct to be used in hashlist") network devices may have alternate
|
|
Jiri Bohac |
340041 |
names. __dev_alloc_name() does take these alternate names into account when looking
|
|
Jiri Bohac |
340041 |
for the device number, possibly generating a name that is already taken, failing with
|
|
Jiri Bohac |
340041 |
-ENFILE as a result.
|
|
Jiri Bohac |
340041 |
|
|
Jiri Bohac |
340041 |
This can easily be reproduced:
|
|
Jiri Bohac |
340041 |
|
|
Jiri Bohac |
340041 |
# rmmod dummy 2>/dev/null
|
|
Jiri Bohac |
340041 |
# ip link property add dev lo altname dummy0
|
|
Jiri Bohac |
340041 |
# modprobe dummy num_dummies=1
|
|
Jiri Bohac |
340041 |
modprobe: ERROR: could not insert 'dummy': Too many open files in system
|
|
Jiri Bohac |
340041 |
|
|
Jiri Bohac |
340041 |
Instead of creating a device named dummy1, the operation fails.
|
|
Jiri Bohac |
340041 |
|
|
Jiri Bohac |
340041 |
Fix this by checking all the names in the dev->name_node list, not just dev->name.
|
|
Jiri Bohac |
340041 |
|
|
Jiri Bohac |
340041 |
Signed-off-by: Jiri Bohac <jbohac@suse.cz>
|
|
Jiri Bohac |
340041 |
Fixes: ff92741270bf ("net: introduce name_node struct to be used in hashlist")
|
|
Jiri Bohac |
340041 |
|
|
Jiri Bohac |
340041 |
diff --git a/net/core/dev.c b/net/core/dev.c
|
|
Jiri Bohac |
340041 |
index 6c5967e80132..7cbcd8d37e91 100644
|
|
Jiri Bohac |
340041 |
--- a/net/core/dev.c
|
|
Jiri Bohac |
340041 |
+++ b/net/core/dev.c
|
|
Jiri Bohac |
340041 |
@@ -1184,6 +1184,18 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf)
|
|
Jiri Bohac |
340041 |
return -ENOMEM;
|
|
Jiri Bohac |
340041 |
|
|
Jiri Bohac |
340041 |
for_each_netdev(net, d) {
|
|
Jiri Bohac |
340041 |
+ struct netdev_name_node *name_node;
|
|
Jiri Bohac |
340041 |
+ list_for_each_entry(name_node, &d->name_node->list, list) {
|
|
Jiri Bohac |
340041 |
+ if (!sscanf(name_node->name, name, &i))
|
|
Jiri Bohac |
340041 |
+ continue;
|
|
Jiri Bohac |
340041 |
+ if (i < 0 || i >= max_netdevices)
|
|
Jiri Bohac |
340041 |
+ continue;
|
|
Jiri Bohac |
340041 |
+
|
|
Jiri Bohac |
340041 |
+ /* avoid cases where sscanf is not exact inverse of printf */
|
|
Jiri Bohac |
340041 |
+ snprintf(buf, IFNAMSIZ, name, i);
|
|
Jiri Bohac |
340041 |
+ if (!strncmp(buf, name_node->name, IFNAMSIZ))
|
|
Jiri Bohac |
340041 |
+ set_bit(i, inuse);
|
|
Jiri Bohac |
340041 |
+ }
|
|
Jiri Bohac |
340041 |
if (!sscanf(d->name, name, &i))
|
|
Jiri Bohac |
340041 |
continue;
|
|
Jiri Bohac |
340041 |
if (i < 0 || i >= max_netdevices)
|
|
Jeff Mahoney |
bb0636 |
|