Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+32 −14
Original line number Diff line number Diff line
@@ -120,8 +120,8 @@ struct tun_sock;
struct tun_struct {
	struct tun_file		*tfile;
	unsigned int 		flags;
	uid_t			owner;
	gid_t			group;
	kuid_t			owner;
	kgid_t			group;

	struct net_device	*dev;
	netdev_features_t	set_features;
@@ -1032,8 +1032,8 @@ static void tun_setup(struct net_device *dev)
{
	struct tun_struct *tun = netdev_priv(dev);

	tun->owner = -1;
	tun->group = -1;
	tun->owner = INVALID_UID;
	tun->group = INVALID_GID;

	dev->ethtool_ops = &tun_ethtool_ops;
	dev->destructor = tun_free_netdev;
@@ -1156,14 +1156,20 @@ static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr,
			      char *buf)
{
	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,
			      char *buf)
{
	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);
@@ -1190,8 +1196,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
		else
			return -EINVAL;

		if (((tun->owner != -1 && cred->euid != tun->owner) ||
		     (tun->group != -1 && !in_egroup_p(tun->group))) &&
		if (((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||
		     (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
		    !capable(CAP_NET_ADMIN))
			return -EPERM;
		err = security_tun_dev_attach(tun->socket.sk);
@@ -1375,6 +1381,8 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
	void __user* argp = (void __user*)arg;
	struct sock_fprog fprog;
	struct ifreq ifr;
	kuid_t owner;
	kgid_t group;
	int sndbuf;
	int vnet_hdr_sz;
	int ret;
@@ -1448,16 +1456,26 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,

	case TUNSETOWNER:
		/* Set owner of the device */
		tun->owner = (uid_t) arg;

		tun_debug(KERN_INFO, tun, "owner set to %d\n", tun->owner);
		owner = make_kuid(current_user_ns(), arg);
		if (!uid_valid(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;

	case TUNSETGROUP:
		/* Set group of the device */
		tun->group= (gid_t) arg;

		tun_debug(KERN_INFO, tun, "group set to %d\n", tun->group);
		group = make_kgid(current_user_ns(), arg);
		if (!gid_valid(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;

	case TUNSETLINK:
+0 −1
Original line number Diff line number Diff line
@@ -1003,7 +1003,6 @@ config UIDGID_CONVERTED
	depends on !UML || HOSTFS = n

	# The rare drivers that won't build
	depends on TUN = n
	depends on INFINIBAND_QIB = n
	depends on BLK_DEV_LOOP = n
	depends on ANDROID_BINDER_IPC = n