diff options
author | David S. Miller <davem@davemloft.net> | 2008-04-23 19:37:58 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-23 19:37:58 -0700 |
commit | 48abfe05cd01279afe27159e98d7c7f932598f42 (patch) | |
tree | b2a408b97806ee86003a804734972523453b8164 /drivers | |
parent | 8c0469cdd08df4dacabc8ca33256ce20de43d73f (diff) | |
download | linux-3.10-48abfe05cd01279afe27159e98d7c7f932598f42.tar.gz linux-3.10-48abfe05cd01279afe27159e98d7c7f932598f42.tar.bz2 linux-3.10-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')
-rw-r--r-- | drivers/net/tun.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index d91856b19f6..d8b1ba15aa6 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: |