tun: Fix minor race in TUNSETLINK ioctl handling.
authorDavid S. Miller <davem@davemloft.net>
Thu, 24 Apr 2008 02:37:58 +0000 (19:37 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 24 Apr 2008 02:37:58 +0000 (19:37 -0700)
Noticed by Alan Cox.

The IFF_UP test is a bit racey, because other entities
outside of this driver's ioctl handler can modify that
state, even though this ioctl handler runs under
lock_kernel().

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/tun.c

index d91856b19f6fdaff4322576af492d107c2c8e8aa..d8b1ba15aa6f6d9060f74c9ad2182eccc63c99c4 100644 (file)
@@ -668,16 +668,23 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                break;
 
        case TUNSETLINK:
+       {
+               int ret;
+
                /* Only allow setting the type when the interface is down */
+               rtnl_lock();
                if (tun->dev->flags & IFF_UP) {
                        DBG(KERN_INFO "%s: Linktype set failed because interface is up\n",
                                tun->dev->name);
-                       return -EBUSY;
+                       ret = -EBUSY;
                } else {
                        tun->dev->type = (int) arg;
                        DBG(KERN_INFO "%s: linktype set to %d\n", tun->dev->name, tun->dev->type);
+                       ret = 0;
                }
-               break;
+               rtnl_unlock();
+               return ret;
+       }
 
 #ifdef TUN_DEBUG
        case TUNSETDEBUG: