]>
Commit | Line | Data |
---|---|---|
5fc11b09 | 1 | diff -Nru a/net/core/dev.c b/net/core/dev.c |
2 | --- a/net/core/dev.c Tue Jan 13 14:20:51 2004 | |
3 | +++ b/net/core/dev.c Tue Jan 13 14:20:51 2004 | |
4 | @@ -621,6 +621,21 @@ | |
5 | } | |
6 | ||
7 | /** | |
8 | + * dev_valid_name - check if name is okay for network device | |
9 | + * @name: name string | |
10 | + * | |
11 | + * Network device names need to be valid file names to | |
12 | + * to allow sysfs to work | |
13 | + */ | |
14 | +int dev_valid_name(const char *name) | |
15 | +{ | |
16 | + return !(*name == '\0' | |
17 | + || !strcmp(name, ".") | |
18 | + || !strcmp(name, "..") | |
19 | + || strchr(name, '/')); | |
20 | +} | |
21 | + | |
22 | +/** | |
23 | * dev_alloc_name - allocate a name for a device | |
24 | * @dev: device | |
25 | * @name: name format string | |
26 | @@ -660,6 +675,41 @@ | |
27 | return -ENFILE; /* Over 100 of the things .. bail out! */ | |
28 | } | |
29 | ||
30 | + | |
31 | +/** | |
32 | + * dev_change_name - change name of a device | |
33 | + * @dev: device | |
34 | + * @name: name (or format string) must be at least IFNAMSIZ | |
35 | + * | |
36 | + * Change name of a device, can pass format strings "eth%d". | |
37 | + * for wildcarding. | |
38 | + */ | |
39 | +int dev_change_name(struct net_device *dev, char *newname) | |
40 | +{ | |
41 | + ASSERT_RTNL(); | |
42 | + | |
43 | + if (dev->flags & IFF_UP) | |
44 | + return -EBUSY; | |
45 | + | |
46 | + if (!dev_valid_name(newname)) | |
47 | + return -EINVAL; | |
48 | + | |
49 | + if (strchr(newname, '%')) { | |
50 | + int err = dev_alloc_name(dev, newname); | |
51 | + if (err) | |
52 | + return err; | |
53 | + strcpy(newname, dev->name); | |
54 | + } | |
55 | + else if (__dev_get_by_name(newname)) | |
56 | + return -EEXIST; | |
57 | + else | |
58 | + strlcpy(dev->name, newname, IFNAMSIZ); | |
59 | + | |
60 | + class_device_rename(&dev->class_dev, dev->name); | |
61 | + notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); | |
62 | + return 0; | |
63 | +} | |
64 | + | |
65 | /** | |
66 | * dev_alloc - allocate a network device and name | |
67 | * @name: name format string | |
68 | @@ -2359,20 +2409,8 @@ | |
69 | return 0; | |
70 | ||
71 | case SIOCSIFNAME: | |
72 | - if (dev->flags & IFF_UP) | |
73 | - return -EBUSY; | |
74 | ifr->ifr_newname[IFNAMSIZ-1] = '\0'; | |
75 | - if (__dev_get_by_name(ifr->ifr_newname)) | |
76 | - return -EEXIST; | |
77 | - err = class_device_rename(&dev->class_dev, | |
78 | - ifr->ifr_newname); | |
79 | - if (!err) { | |
80 | - strlcpy(dev->name, ifr->ifr_newname, IFNAMSIZ); | |
81 | - | |
82 | - notifier_call_chain(&netdev_chain, | |
83 | - NETDEV_CHANGENAME, dev); | |
84 | - } | |
85 | - return err; | |
86 | + return dev_change_name(dev, ifr->ifr_newname); | |
87 | ||
88 | /* | |
89 | * Unknown or private ioctl | |
90 | @@ -2505,6 +2543,7 @@ | |
91 | */ | |
92 | case SIOCGMIIPHY: | |
93 | case SIOCGMIIREG: | |
94 | + case SIOCSIFNAME: | |
95 | if (!capable(CAP_NET_ADMIN)) | |
96 | return -EPERM; | |
97 | dev_load(ifr.ifr_name); | |
98 | @@ -2536,7 +2575,6 @@ | |
99 | case SIOCDELMULTI: | |
100 | case SIOCSIFHWBROADCAST: | |
101 | case SIOCSIFTXQLEN: | |
102 | - case SIOCSIFNAME: | |
103 | case SIOCSMIIREG: | |
104 | case SIOCBONDENSLAVE: | |
105 | case SIOCBONDRELEASE: | |
106 | @@ -2685,6 +2723,11 @@ | |
107 | ret = -EIO; | |
108 | goto out_err; | |
109 | } | |
110 | + } | |
111 | + | |
112 | + if (!dev_valid_name(dev->name)) { | |
113 | + ret = -EINVAL; | |
114 | + goto out_err; | |
115 | } | |
116 | ||
117 | dev->ifindex = dev_new_index(); |