aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido Guenther <agx@sigxcpu.org>2007-07-03 01:50:25 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-11 01:16:42 -0400
commit8c644623fe7e41f59fe97cdf666cba3cb7ced7d8 (patch)
tree42ed72e59e73b6ec840aa4ea97a34630f3544093
parent0ba48053831d5b89ee2afaefaae1c06eae80cb05 (diff)
[NET]: Allow group ownership of TUN/TAP devices.
Introduce a new syscall TUNSETGROUP for group ownership setting of tap devices. The user now is allowed to send packages if either his euid or his egid matches the one specified via tunctl (via -u or -g respecitvely). If both, gid and uid, are set via tunctl, both have to match. Signed-off-by: Guido Guenther <agx@sigxcpu.org> Signed-off-by: Jeff Dike <jdike@linux.intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-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