aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/tun.c15
-rw-r--r--include/linux/if_tun.h2
2 files changed, 15 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) {
diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h
index 88aef7b86ef4..42eb6945b93e 100644
--- a/include/linux/if_tun.h
+++ b/include/linux/if_tun.h
@@ -36,6 +36,7 @@ struct tun_struct {
36 unsigned long flags; 36 unsigned long flags;
37 int attached; 37 int attached;
38 uid_t owner; 38 uid_t owner;
39 gid_t group;
39 40
40 wait_queue_head_t read_wait; 41 wait_queue_head_t read_wait;
41 struct sk_buff_head readq; 42 struct sk_buff_head readq;
@@ -78,6 +79,7 @@ struct tun_struct {
78#define TUNSETPERSIST _IOW('T', 203, int) 79#define TUNSETPERSIST _IOW('T', 203, int)
79#define TUNSETOWNER _IOW('T', 204, int) 80#define TUNSETOWNER _IOW('T', 204, int)
80#define TUNSETLINK _IOW('T', 205, int) 81#define TUNSETLINK _IOW('T', 205, int)
82#define TUNSETGROUP _IOW('T', 206, int)
81 83
82/* TUNSETIFF ifr flags */ 84/* TUNSETIFF ifr flags */
83#define IFF_TUN 0x0001 85#define IFF_TUN 0x0001