aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-04-23 22:37:58 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-23 22:37:58 -0400
commit48abfe05cd01279afe27159e98d7c7f932598f42 (patch)
treeb2a408b97806ee86003a804734972523453b8164 /drivers/net/tun.c
parent8c0469cdd08df4dacabc8ca33256ce20de43d73f (diff)
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,
668 break; 668 break;
669 669
670 case TUNSETLINK: 670 case TUNSETLINK:
671 {
672 int ret;
673
671 /* Only allow setting the type when the interface is down */ 674 /* Only allow setting the type when the interface is down */
675 rtnl_lock();
672 if (tun->dev->flags & IFF_UP) { 676 if (tun->dev->flags & IFF_UP) {
673 DBG(KERN_INFO "%s: Linktype set failed because interface is up\n", 677 DBG(KERN_INFO "%s: Linktype set failed because interface is up\n",
674 tun->dev->name); 678 tun->dev->name);
675 return -EBUSY; 679 ret = -EBUSY;
676 } else { 680 } else {
677 tun->dev->type = (int) arg; 681 tun->dev->type = (int) arg;
678 DBG(KERN_INFO "%s: linktype set to %d\n", tun->dev->name, tun->dev->type); 682 DBG(KERN_INFO "%s: linktype set to %d\n", tun->dev->name, tun->dev->type);
683 ret = 0;
679 } 684 }
680 break; 685 rtnl_unlock();
686 return ret;
687 }
681 688
682#ifdef TUN_DEBUG 689#ifdef TUN_DEBUG
683 case TUNSETDEBUG: 690 case TUNSETDEBUG: