aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index a2c6caaaae93..62b2b3005019 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -432,6 +432,7 @@ static void tun_setup(struct net_device *dev)
432 init_waitqueue_head(&tun->read_wait); 432 init_waitqueue_head(&tun->read_wait);
433 433
434 tun->owner = -1; 434 tun->owner = -1;
435 tun->group = -1;
435 436
436 SET_MODULE_OWNER(dev); 437 SET_MODULE_OWNER(dev);
437 dev->open = tun_net_open; 438 dev->open = tun_net_open;
@@ -467,8 +468,11 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
467 return -EBUSY; 468 return -EBUSY;
468 469
469 /* Check permissions */ 470 /* Check permissions */
470 if (tun->owner != -1 && 471 if (((tun->owner != -1 &&
471 current->euid != tun->owner && !capable(CAP_NET_ADMIN)) 472 current->euid != tun->owner) ||
473 (tun->group != -1 &&
474 current->egid != tun->group)) &&
475 !capable(CAP_NET_ADMIN))
472 return -EPERM; 476 return -EPERM;
473 } 477 }
474 else if (__dev_get_by_name(ifr->ifr_name)) 478 else if (__dev_get_by_name(ifr->ifr_name))
@@ -610,6 +614,13 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
610 DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner); 614 DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner);
611 break; 615 break;
612 616
617 case TUNSETGROUP:
618 /* Set group of the device */
619 tun->group= (gid_t) arg;
620
621 DBG(KERN_INFO "%s: group set to %d\n", tun->dev->name, tun->group);
622 break;
623
613 case TUNSETLINK: 624 case TUNSETLINK:
614 /* Only allow setting the type when the interface is down */ 625 /* Only allow setting the type when the interface is down */
615 if (tun->dev->flags & IFF_UP) { 626 if (tun->dev->flags & IFF_UP) {