aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-04-23 19:37:58 -0700
committerDavid S. Miller <davem@davemloft.net>2008-04-23 19:37:58 -0700
commit48abfe05cd01279afe27159e98d7c7f932598f42 (patch)
treeb2a408b97806ee86003a804734972523453b8164 /drivers/net/tun.c
parentppp_generic: use stats from net_device structure (diff)
downloadlinux-dev-48abfe05cd01279afe27159e98d7c7f932598f42.tar.xz
linux-dev-48abfe05cd01279afe27159e98d7c7f932598f42.zip
tun: Fix minor race in TUNSETLINK ioctl handling.
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>
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index d91856b19f6f..d8b1ba15aa6f 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -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: