diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-02-07 19:48:55 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2012-08-15 00:55:31 -0400 |
commit | 0625c883bc4b3eba6f93f268cf67b5664244c0fe (patch) | |
tree | b2fa3da08149f0f6bc7a24e6b380eb173420a372 | |
parent | 1efa29cd414c68725e774d52b248c82d9be44767 (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.c | 46 | ||||
-rw-r--r-- | init/Kconfig | 1 |
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; | |||
120 | struct tun_struct { | 120 | struct 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 | ||
1162 | static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, | 1165 | static 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 | ||
1169 | static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); | 1175 | static 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 |