mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
[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>
This commit is contained in:
committed by
David S. Miller
parent
0ba4805383
commit
8c644623fe
@@ -432,6 +432,7 @@ static void tun_setup(struct net_device *dev)
|
|||||||
init_waitqueue_head(&tun->read_wait);
|
init_waitqueue_head(&tun->read_wait);
|
||||||
|
|
||||||
tun->owner = -1;
|
tun->owner = -1;
|
||||||
|
tun->group = -1;
|
||||||
|
|
||||||
SET_MODULE_OWNER(dev);
|
SET_MODULE_OWNER(dev);
|
||||||
dev->open = tun_net_open;
|
dev->open = tun_net_open;
|
||||||
@@ -467,8 +468,11 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
/* Check permissions */
|
/* Check permissions */
|
||||||
if (tun->owner != -1 &&
|
if (((tun->owner != -1 &&
|
||||||
current->euid != tun->owner && !capable(CAP_NET_ADMIN))
|
current->euid != tun->owner) ||
|
||||||
|
(tun->group != -1 &&
|
||||||
|
current->egid != tun->group)) &&
|
||||||
|
!capable(CAP_NET_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
else if (__dev_get_by_name(ifr->ifr_name))
|
else if (__dev_get_by_name(ifr->ifr_name))
|
||||||
@@ -610,6 +614,13 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
|
|||||||
DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner);
|
DBG(KERN_INFO "%s: owner set to %d\n", tun->dev->name, tun->owner);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TUNSETGROUP:
|
||||||
|
/* Set group of the device */
|
||||||
|
tun->group= (gid_t) arg;
|
||||||
|
|
||||||
|
DBG(KERN_INFO "%s: group set to %d\n", tun->dev->name, tun->group);
|
||||||
|
break;
|
||||||
|
|
||||||
case TUNSETLINK:
|
case TUNSETLINK:
|
||||||
/* Only allow setting the type when the interface is down */
|
/* Only allow setting the type when the interface is down */
|
||||||
if (tun->dev->flags & IFF_UP) {
|
if (tun->dev->flags & IFF_UP) {
|
||||||
|
@@ -36,6 +36,7 @@ struct tun_struct {
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int attached;
|
int attached;
|
||||||
uid_t owner;
|
uid_t owner;
|
||||||
|
gid_t group;
|
||||||
|
|
||||||
wait_queue_head_t read_wait;
|
wait_queue_head_t read_wait;
|
||||||
struct sk_buff_head readq;
|
struct sk_buff_head readq;
|
||||||
@@ -78,6 +79,7 @@ struct tun_struct {
|
|||||||
#define TUNSETPERSIST _IOW('T', 203, int)
|
#define TUNSETPERSIST _IOW('T', 203, int)
|
||||||
#define TUNSETOWNER _IOW('T', 204, int)
|
#define TUNSETOWNER _IOW('T', 204, int)
|
||||||
#define TUNSETLINK _IOW('T', 205, int)
|
#define TUNSETLINK _IOW('T', 205, int)
|
||||||
|
#define TUNSETGROUP _IOW('T', 206, int)
|
||||||
|
|
||||||
/* TUNSETIFF ifr flags */
|
/* TUNSETIFF ifr flags */
|
||||||
#define IFF_TUN 0x0001
|
#define IFF_TUN 0x0001
|
||||||
|
Reference in New Issue
Block a user