aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorWANG Cong <xiyou.wangcong@gmail.com>2014-07-25 18:25:08 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-29 14:43:50 -0400
commit20e61da7ffcfd84a1b6f797e745608572e5bc218 (patch)
tree19738d56563acf91956bb2a0b44de9ff2e1640cd /net/ipv4
parent9d7e3ea73c6be20538a69c14ab8bfb3b36f8d1a8 (diff)
ipv4: fail early when creating netdev named all or default
We create a proc dir for each network device, this will cause conflicts when the devices have name "all" or "default". Rather than emitting an ugly kernel warning, we could just fail earlier by checking the device name. Reported-by: Stephane Chazelas <stephane.chazelas@gmail.com> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/devinet.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index e9449376b58e..214882e7d6de 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -180,11 +180,12 @@ static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
180static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, 180static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
181 int destroy); 181 int destroy);
182#ifdef CONFIG_SYSCTL 182#ifdef CONFIG_SYSCTL
183static void devinet_sysctl_register(struct in_device *idev); 183static int devinet_sysctl_register(struct in_device *idev);
184static void devinet_sysctl_unregister(struct in_device *idev); 184static void devinet_sysctl_unregister(struct in_device *idev);
185#else 185#else
186static void devinet_sysctl_register(struct in_device *idev) 186static int devinet_sysctl_register(struct in_device *idev)
187{ 187{
188 return 0;
188} 189}
189static void devinet_sysctl_unregister(struct in_device *idev) 190static void devinet_sysctl_unregister(struct in_device *idev)
190{ 191{
@@ -232,6 +233,7 @@ EXPORT_SYMBOL(in_dev_finish_destroy);
232static struct in_device *inetdev_init(struct net_device *dev) 233static struct in_device *inetdev_init(struct net_device *dev)
233{ 234{
234 struct in_device *in_dev; 235 struct in_device *in_dev;
236 int err = -ENOMEM;
235 237
236 ASSERT_RTNL(); 238 ASSERT_RTNL();
237 239
@@ -252,7 +254,13 @@ static struct in_device *inetdev_init(struct net_device *dev)
252 /* Account for reference dev->ip_ptr (below) */ 254 /* Account for reference dev->ip_ptr (below) */
253 in_dev_hold(in_dev); 255 in_dev_hold(in_dev);
254 256
255 devinet_sysctl_register(in_dev); 257 err = devinet_sysctl_register(in_dev);
258 if (err) {
259 in_dev->dead = 1;
260 in_dev_put(in_dev);
261 in_dev = NULL;
262 goto out;
263 }
256 ip_mc_init_dev(in_dev); 264 ip_mc_init_dev(in_dev);
257 if (dev->flags & IFF_UP) 265 if (dev->flags & IFF_UP)
258 ip_mc_up(in_dev); 266 ip_mc_up(in_dev);
@@ -260,7 +268,7 @@ static struct in_device *inetdev_init(struct net_device *dev)
260 /* we can receive as soon as ip_ptr is set -- do this last */ 268 /* we can receive as soon as ip_ptr is set -- do this last */
261 rcu_assign_pointer(dev->ip_ptr, in_dev); 269 rcu_assign_pointer(dev->ip_ptr, in_dev);
262out: 270out:
263 return in_dev; 271 return in_dev ?: ERR_PTR(err);
264out_kfree: 272out_kfree:
265 kfree(in_dev); 273 kfree(in_dev);
266 in_dev = NULL; 274 in_dev = NULL;
@@ -1347,8 +1355,8 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
1347 if (!in_dev) { 1355 if (!in_dev) {
1348 if (event == NETDEV_REGISTER) { 1356 if (event == NETDEV_REGISTER) {
1349 in_dev = inetdev_init(dev); 1357 in_dev = inetdev_init(dev);
1350 if (!in_dev) 1358 if (IS_ERR(in_dev))
1351 return notifier_from_errno(-ENOMEM); 1359 return notifier_from_errno(PTR_ERR(in_dev));
1352 if (dev->flags & IFF_LOOPBACK) { 1360 if (dev->flags & IFF_LOOPBACK) {
1353 IN_DEV_CONF_SET(in_dev, NOXFRM, 1); 1361 IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
1354 IN_DEV_CONF_SET(in_dev, NOPOLICY, 1); 1362 IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
@@ -2182,11 +2190,21 @@ static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
2182 kfree(t); 2190 kfree(t);
2183} 2191}
2184 2192
2185static void devinet_sysctl_register(struct in_device *idev) 2193static int devinet_sysctl_register(struct in_device *idev)
2186{ 2194{
2187 neigh_sysctl_register(idev->dev, idev->arp_parms, NULL); 2195 int err;
2188 __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name, 2196
2197 if (!sysctl_dev_name_is_allowed(idev->dev->name))
2198 return -EINVAL;
2199
2200 err = neigh_sysctl_register(idev->dev, idev->arp_parms, NULL);
2201 if (err)
2202 return err;
2203 err = __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name,
2189 &idev->cnf); 2204 &idev->cnf);
2205 if (err)
2206 neigh_sysctl_unregister(idev->arp_parms);
2207 return err;
2190} 2208}
2191 2209
2192static void devinet_sysctl_unregister(struct in_device *idev) 2210static void devinet_sysctl_unregister(struct in_device *idev)