aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-02-07 19:48:55 -0500
committerEric W. Biederman <ebiederm@xmission.com>2012-08-15 00:55:31 -0400
commit0625c883bc4b3eba6f93f268cf67b5664244c0fe (patch)
treeb2fa3da08149f0f6bc7a24e6b380eb173420a372
parent1efa29cd414c68725e774d52b248c82d9be44767 (diff)
userns: Convert tun/tap to use kuid and kgid where appropriate
Cc: Maxim Krasnyansky <maxk@qualcomm.com> Acked-by: David S. Miller <davem@davemloft.net> Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
-rw-r--r--drivers/net/tun.c46
-rw-r--r--init/Kconfig1
2 files changed, 32 insertions, 15 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 926d4db5cb38..a9bd9f384f5f 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -120,8 +120,8 @@ struct tun_sock;
120struct tun_struct { 120struct tun_struct {
121 struct tun_file *tfile; 121 struct tun_file *tfile;
122 unsigned int flags; 122 unsigned int flags;
123 uid_t owner; 123 kuid_t owner;
124 gid_t group; 124 kgid_t group;
125 125
126 struct net_device *dev; 126 struct net_device *dev;
127 netdev_features_t set_features; 127 netdev_features_t set_features;
@@ -1032,8 +1032,8 @@ static void tun_setup(struct net_device *dev)
1032{ 1032{
1033 struct tun_struct *tun = netdev_priv(dev); 1033 struct tun_struct *tun = netdev_priv(dev);
1034 1034
1035 tun->owner = -1; 1035 tun->owner = INVALID_UID;
1036 tun->group = -1; 1036 tun->group = INVALID_GID;
1037 1037
1038 dev->ethtool_ops = &tun_ethtool_ops; 1038 dev->ethtool_ops = &tun_ethtool_ops;
1039 dev->destructor = tun_free_netdev; 1039 dev->destructor = tun_free_netdev;
@@ -1156,14 +1156,20 @@ static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr,
1156 char *buf) 1156 char *buf)
1157{ 1157{
1158 struct tun_struct *tun = netdev_priv(to_net_dev(dev)); 1158 struct tun_struct *tun = netdev_priv(to_net_dev(dev));
1159 return sprintf(buf, "%d\n", tun->owner); 1159 return uid_valid(tun->owner)?
1160 sprintf(buf, "%u\n",
1161 from_kuid_munged(current_user_ns(), tun->owner)):
1162 sprintf(buf, "-1\n");
1160} 1163}
1161 1164
1162static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, 1165static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr,
1163 char *buf) 1166 char *buf)
1164{ 1167{
1165 struct tun_struct *tun = netdev_priv(to_net_dev(dev)); 1168 struct tun_struct *tun = netdev_priv(to_net_dev(dev));
1166 return sprintf(buf, "%d\n", tun->group); 1169 return gid_valid(tun->group) ?
1170 sprintf(buf, "%u\n",
1171 from_kgid_munged(current_user_ns(), tun->group)):
1172 sprintf(buf, "-1\n");
1167} 1173}
1168 1174
1169static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); 1175static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL);
@@ -1190,8 +1196,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
1190 else 1196 else
1191 return -EINVAL; 1197 return -EINVAL;
1192 1198
1193 if (((tun->owner != -1 && cred->euid != tun->owner) || 1199 if (((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||
1194 (tun->group != -1 && !in_egroup_p(tun->group))) && 1200 (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
1195 !capable(CAP_NET_ADMIN)) 1201 !capable(CAP_NET_ADMIN))
1196 return -EPERM; 1202 return -EPERM;
1197 err = security_tun_dev_attach(tun->socket.sk); 1203 err = security_tun_dev_attach(tun->socket.sk);
@@ -1375,6 +1381,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1375 void __user* argp = (void __user*)arg; 1381 void __user* argp = (void __user*)arg;
1376 struct sock_fprog fprog; 1382 struct sock_fprog fprog;
1377 struct ifreq ifr; 1383 struct ifreq ifr;
1384 kuid_t owner;
1385 kgid_t group;
1378 int sndbuf; 1386 int sndbuf;
1379 int vnet_hdr_sz; 1387 int vnet_hdr_sz;
1380 int ret; 1388 int ret;
@@ -1448,16 +1456,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1448 1456
1449 case TUNSETOWNER: 1457 case TUNSETOWNER:
1450 /* Set owner of the device */ 1458 /* Set owner of the device */
1451 tun->owner = (uid_t) arg; 1459 owner = make_kuid(current_user_ns(), arg);
1452 1460 if (!uid_valid(owner)) {
1453 tun_debug(KERN_INFO, tun, "owner set to %d\n", tun->owner); 1461 ret = -EINVAL;
1462 break;
1463 }
1464 tun->owner = owner;
1465 tun_debug(KERN_INFO, tun, "owner set to %d\n",
1466 from_kuid(&init_user_ns, tun->owner));
1454 break; 1467 break;
1455 1468
1456 case TUNSETGROUP: 1469 case TUNSETGROUP:
1457 /* Set group of the device */ 1470 /* Set group of the device */
1458 tun->group= (gid_t) arg; 1471 group = make_kgid(current_user_ns(), arg);
1459 1472 if (!gid_valid(group)) {
1460 tun_debug(KERN_INFO, tun, "group set to %d\n", tun->group); 1473 ret = -EINVAL;
1474 break;
1475 }
1476 tun->group = group;
1477 tun_debug(KERN_INFO, tun, "group set to %d\n",
1478 from_kgid(&init_user_ns, tun->group));
1461 break; 1479 break;
1462 1480
1463 case TUNSETLINK: 1481 case TUNSETLINK:
diff --git a/init/Kconfig b/init/Kconfig
index eac23a6fa236..b445d6f49bcf 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1003,7 +1003,6 @@ config UIDGID_CONVERTED
1003 depends on !UML || HOSTFS = n 1003 depends on !UML || HOSTFS = n
1004 1004
1005 # The rare drivers that won't build 1005 # The rare drivers that won't build
1006 depends on TUN = n
1007 depends on INFINIBAND_QIB = n 1006 depends on INFINIBAND_QIB = n
1008 depends on BLK_DEV_LOOP = n 1007 depends on BLK_DEV_LOOP = n
1009 depends on ANDROID_BINDER_IPC = n 1008 depends on ANDROID_BINDER_IPC = n