Commit 0625c883 authored by Eric W. Biederman's avatar Eric W. Biederman

userns: Convert tun/tap to use kuid and kgid where appropriate

Cc: Maxim Krasnyansky <maxk@qualcomm.com>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Acked-by: default avatarSerge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
parent 1efa29cd
...@@ -120,8 +120,8 @@ struct tun_sock; ...@@ -120,8 +120,8 @@ struct tun_sock;
struct tun_struct { struct tun_struct {
struct tun_file *tfile; struct tun_file *tfile;
unsigned int flags; unsigned int flags;
uid_t owner; kuid_t owner;
gid_t group; kgid_t group;
struct net_device *dev; struct net_device *dev;
netdev_features_t set_features; netdev_features_t set_features;
...@@ -1032,8 +1032,8 @@ static void tun_setup(struct net_device *dev) ...@@ -1032,8 +1032,8 @@ static void tun_setup(struct net_device *dev)
{ {
struct tun_struct *tun = netdev_priv(dev); struct tun_struct *tun = netdev_priv(dev);
tun->owner = -1; tun->owner = INVALID_UID;
tun->group = -1; tun->group = INVALID_GID;
dev->ethtool_ops = &tun_ethtool_ops; dev->ethtool_ops = &tun_ethtool_ops;
dev->destructor = tun_free_netdev; dev->destructor = tun_free_netdev;
...@@ -1156,14 +1156,20 @@ static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr, ...@@ -1156,14 +1156,20 @@ static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct tun_struct *tun = netdev_priv(to_net_dev(dev)); struct tun_struct *tun = netdev_priv(to_net_dev(dev));
return sprintf(buf, "%d\n", tun->owner); return uid_valid(tun->owner)?
sprintf(buf, "%u\n",
from_kuid_munged(current_user_ns(), tun->owner)):
sprintf(buf, "-1\n");
} }
static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr, static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct tun_struct *tun = netdev_priv(to_net_dev(dev)); struct tun_struct *tun = netdev_priv(to_net_dev(dev));
return sprintf(buf, "%d\n", tun->group); return gid_valid(tun->group) ?
sprintf(buf, "%u\n",
from_kgid_munged(current_user_ns(), tun->group)):
sprintf(buf, "-1\n");
} }
static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL); 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,8 +1196,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
else else
return -EINVAL; return -EINVAL;
if (((tun->owner != -1 && cred->euid != tun->owner) || if (((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||
(tun->group != -1 && !in_egroup_p(tun->group))) && (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
!capable(CAP_NET_ADMIN)) !capable(CAP_NET_ADMIN))
return -EPERM; return -EPERM;
err = security_tun_dev_attach(tun->socket.sk); err = security_tun_dev_attach(tun->socket.sk);
...@@ -1375,6 +1381,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, ...@@ -1375,6 +1381,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
void __user* argp = (void __user*)arg; void __user* argp = (void __user*)arg;
struct sock_fprog fprog; struct sock_fprog fprog;
struct ifreq ifr; struct ifreq ifr;
kuid_t owner;
kgid_t group;
int sndbuf; int sndbuf;
int vnet_hdr_sz; int vnet_hdr_sz;
int ret; int ret;
...@@ -1448,16 +1456,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, ...@@ -1448,16 +1456,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
case TUNSETOWNER: case TUNSETOWNER:
/* Set owner of the device */ /* Set owner of the device */
tun->owner = (uid_t) arg; owner = make_kuid(current_user_ns(), arg);
if (!uid_valid(owner)) {
tun_debug(KERN_INFO, tun, "owner set to %d\n", tun->owner); ret = -EINVAL;
break;
}
tun->owner = owner;
tun_debug(KERN_INFO, tun, "owner set to %d\n",
from_kuid(&init_user_ns, tun->owner));
break; break;
case TUNSETGROUP: case TUNSETGROUP:
/* Set group of the device */ /* Set group of the device */
tun->group= (gid_t) arg; group = make_kgid(current_user_ns(), arg);
if (!gid_valid(group)) {
tun_debug(KERN_INFO, tun, "group set to %d\n", tun->group); ret = -EINVAL;
break;
}
tun->group = group;
tun_debug(KERN_INFO, tun, "group set to %d\n",
from_kgid(&init_user_ns, tun->group));
break; break;
case TUNSETLINK: case TUNSETLINK:
......
...@@ -1003,7 +1003,6 @@ config UIDGID_CONVERTED ...@@ -1003,7 +1003,6 @@ config UIDGID_CONVERTED
depends on !UML || HOSTFS = n depends on !UML || HOSTFS = n
# The rare drivers that won't build # The rare drivers that won't build
depends on TUN = n
depends on INFINIBAND_QIB = n depends on INFINIBAND_QIB = n
depends on BLK_DEV_LOOP = n depends on BLK_DEV_LOOP = n
depends on ANDROID_BINDER_IPC = n depends on ANDROID_BINDER_IPC = n
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment