Commit b4ec8240 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

rose: device refcount leak

While hunting dev_put() for net-next-2.6, I found a device refcount
leak in ROSE, ioctl(SIOCADDRT) error path.

Fix is to not touch device refcount, as we hold RTNL
Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1056bd51
...@@ -578,18 +578,18 @@ static int rose_clear_routes(void) ...@@ -578,18 +578,18 @@ static int rose_clear_routes(void)
/* /*
* Check that the device given is a valid AX.25 interface that is "up". * Check that the device given is a valid AX.25 interface that is "up".
* called whith RTNL
*/ */
static struct net_device *rose_ax25_dev_get(char *devname) static struct net_device *rose_ax25_dev_find(char *devname)
{ {
struct net_device *dev; struct net_device *dev;
if ((dev = dev_get_by_name(&init_net, devname)) == NULL) if ((dev = __dev_get_by_name(&init_net, devname)) == NULL)
return NULL; return NULL;
if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25) if ((dev->flags & IFF_UP) && dev->type == ARPHRD_AX25)
return dev; return dev;
dev_put(dev);
return NULL; return NULL;
} }
...@@ -720,27 +720,23 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg) ...@@ -720,27 +720,23 @@ int rose_rt_ioctl(unsigned int cmd, void __user *arg)
case SIOCADDRT: case SIOCADDRT:
if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
return -EFAULT; return -EFAULT;
if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL) if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
return -EINVAL; return -EINVAL;
if (rose_dev_exists(&rose_route.address)) { /* Can't add routes to ourself */ if (rose_dev_exists(&rose_route.address)) /* Can't add routes to ourself */
dev_put(dev);
return -EINVAL; return -EINVAL;
}
if (rose_route.mask > 10) /* Mask can't be more than 10 digits */ if (rose_route.mask > 10) /* Mask can't be more than 10 digits */
return -EINVAL; return -EINVAL;
if (rose_route.ndigis > AX25_MAX_DIGIS) if (rose_route.ndigis > AX25_MAX_DIGIS)
return -EINVAL; return -EINVAL;
err = rose_add_node(&rose_route, dev); err = rose_add_node(&rose_route, dev);
dev_put(dev);
return err; return err;
case SIOCDELRT: case SIOCDELRT:
if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct))) if (copy_from_user(&rose_route, arg, sizeof(struct rose_route_struct)))
return -EFAULT; return -EFAULT;
if ((dev = rose_ax25_dev_get(rose_route.device)) == NULL) if ((dev = rose_ax25_dev_find(rose_route.device)) == NULL)
return -EINVAL; return -EINVAL;
err = rose_del_node(&rose_route, dev); err = rose_del_node(&rose_route, dev);
dev_put(dev);
return err; return err;
case SIOCRSCLRRT: case SIOCRSCLRRT:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment