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.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 3a16d4fdaa05..498dc0d4ba5e 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;
@@ -1031,8 +1031,8 @@ static void tun_setup(struct net_device *dev)
1031{ 1031{
1032 struct tun_struct *tun = netdev_priv(dev); 1032 struct tun_struct *tun = netdev_priv(dev);
1033 1033
1034 tun->owner = -1; 1034 tun->owner = INVALID_UID;
1035 tun->group = -1; 1035 tun->group = INVALID_GID;
1036 1036
1037 dev->ethtool_ops = &tun_ethtool_ops; 1037 dev->ethtool_ops = &tun_ethtool_ops;
1038 dev->destructor = tun_free_netdev; 1038 dev->destructor = tun_free_netdev;
@@ -1155,14 +1155,20 @@ static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr,
1155 char *buf) 1155 char *buf)
1156{ 1156{
1157 struct tun_struct *tun = netdev_priv(to_net_dev(dev)); 1157 struct tun_struct *tun = netdev_priv(to_net_dev(dev));
1158 return sprintf(buf, "%d\n", tun->owner); 1158 return uid_valid(tun->owner)?
1159 sprintf(buf, "%u\n",
1160 from_kuid_munged(current_user_ns(), tun->owner)):
1161 sprintf(buf, "-1\n");
1159} 1162}
1160 1163
1161static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, 1164static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr,
1162 char *buf) 1165 char *buf)
1163{ 1166{
1164 struct tun_struct *tun = netdev_priv(to_net_dev(dev)); 1167 struct tun_struct *tun = netdev_priv(to_net_dev(dev));
1165 return sprintf(buf, "%d\n", tun->group); 1168 return gid_valid(tun->group) ?
1169 sprintf(buf, "%u\n",
1170 from_kgid_munged(current_user_ns(), tun->group)):
1171 sprintf(buf, "-1\n");
1166} 1172}
1167 1173
1168static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); 1174static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL);
@@ -1189,8 +1195,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
1189 else 1195 else
1190 return -EINVAL; 1196 return -EINVAL;
1191 1197
1192 if (((tun->owner != -1 && cred->euid != tun->owner) || 1198 if (((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||
1193 (tun->group != -1 && !in_egroup_p(tun->group))) && 1199 (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
1194 !capable(CAP_NET_ADMIN)) 1200 !capable(CAP_NET_ADMIN))
1195 return -EPERM; 1201 return -EPERM;
1196 err = security_tun_dev_attach(tun->socket.sk); 1202 err = security_tun_dev_attach(tun->socket.sk);
@@ -1374,6 +1380,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1374 void __user* argp = (void __user*)arg; 1380 void __user* argp = (void __user*)arg;
1375 struct sock_fprog fprog; 1381 struct sock_fprog fprog;
1376 struct ifreq ifr; 1382 struct ifreq ifr;
1383 kuid_t owner;
1384 kgid_t group;
1377 int sndbuf; 1385 int sndbuf;
1378 int vnet_hdr_sz; 1386 int vnet_hdr_sz;
1379 int ret; 1387 int ret;
@@ -1447,16 +1455,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1447 1455
1448 case TUNSETOWNER: 1456 case TUNSETOWNER:
1449 /* Set owner of the device */ 1457 /* Set owner of the device */
1450 tun->owner = (uid_t) arg; 1458 owner = make_kuid(current_user_ns(), arg);
1451 1459 if (!uid_valid(owner)) {
1452 tun_debug(KERN_INFO, tun, "owner set to %d\n", tun->owner); 1460 ret = -EINVAL;
1461 break;
1462 }
1463 tun->owner = owner;
1464 tun_debug(KERN_INFO, tun, "owner set to %d\n",
1465 from_kuid(&init_user_ns, tun->owner));
1453 break; 1466 break;
1454 1467
1455 case TUNSETGROUP: 1468 case TUNSETGROUP:
1456 /* Set group of the device */ 1469 /* Set group of the device */
1457 tun->group= (gid_t) arg; 1470 group = make_kgid(current_user_ns(), arg);
1458 1471 if (!gid_valid(group)) {
1459 tun_debug(KERN_INFO, tun, "group set to %d\n", tun->group); 1472 ret = -EINVAL;
1473 break;
1474 }
1475 tun->group = group;
1476 tun_debug(KERN_INFO, tun, "group set to %d\n",
1477 from_kgid(&init_user_ns, tun->group));
1460 break; 1478 break;
1461 1479
1462 case TUNSETLINK: 1480 case TUNSETLINK: